ex
Fork of mbed-os-example-mbed5-blinky by
Revision 45:2aa9f933c8d2, committed 2017-07-18
- Comitter:
- TMBOY
- Date:
- Tue Jul 18 16:34:48 2017 +0800
- Parent:
- 44:c1d8923072ba
- Child:
- 46:183cfc59d4e4
- Commit message:
- ?
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/.gitignore Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,55 @@ +# Built application files +*.apk +*.ap_ + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# Intellij +*.iml +.idea/workspace.xml +.idea/tasks.xml +.idea/gradle.xml +.idea/dictionaries +.idea/libraries + +# Keystore files +*.jks + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild + +# Google Services (e.g. APIs or Firebase) +google-services.json + +# Freeline +freeline.py +freeline/ +freeline_project_description.json
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/LICENSE.txt Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/README.md Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,71 @@ +# DCS SDK(Java)开发者指南 + +## DCS协议 + +DCS协议是DuerOS服务端与设备端之间的通讯协议,是一套把DuerOS的智能语音交互能力向所有设备开放的API,了解详情请看[DCS协议文档](http://developer.dueros.baidu.com/doc/dueros-conversational-service/introduction_markdown)。 + +## 摘要 + +DCS SDK提供DCS协议在设备端的实现,旨在降低设备接入DuerOS的开发成本。DCS SDK是完整的Sample App,可以直接在目标设备运行,并且源代码全部开源,开发者可以基于源码进行二次开发。 + +本文档介绍的DCS SDK(Java)是Java版本的实现,该版本目前支持Android系统。 + +## 1-前置条件 + +a.完成注册百度账号、开发者认证和产品创建(选择手机场景和Android平台)后,请保存client_id和client_secret + + + +具体参考[控制台接入流程](http://developer.dueros.baidu.com/doc/overall/console-guide_markdown)。 + +b.在百度开发者中心配置OAuth的授权回调页 + 1. 到DuerOS开放平台控制台: http://developer.dueros.baidu.com/openduer/product/getproduct + 2. 点击所创建产品的“编辑”按钮,按钮在右侧 + 3. 点击OAUTH CONFIG URL,到百度开发者平台控制台 + 4. 在开发者平台控制台,点击左侧“安全设置” + 5. 在“授权回调页”输入框中输入"bdconnect://cancel,bdconnect://success"(不带双引号) + 6. 点击页面下方“确定”按钮 + +c.开发环境 + - Android Studio 2.2+ + - Gradle 2.2+ + - Android SDK 5.0+ (支持http/2) + - JDK 1.6+ + +## 2-克隆项目 + +```shell +git clone https://github.com/dueros/dcs-sdk-java.git +``` + +## 3-运行 + +a.通过Android Studio找到DcsSampleOAuthActivity.java,利用上述client_id进行替换 + + + +b.运行(Android真机) + + + +c.百度账号登录 + + + +## 4-唤醒 + +说“小度小度”,成功唤醒后进入“录音中”状态,如下图: + + + +## 5-和小度对话 + +a.通过唤醒或者单击“点击说话”进入录音状态, 问“北京天气怎么样”,DuerOS后端将发送stopListen指令,同时返回speak指令,播报北京天气。 + +b.问“播放刘若英的歌”, 返回play指令播放歌,可以从界面上进行“播放”、“暂停”、“上一首”和“下一首”操作。 + +## 6 SDK结构 + + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/.gitignore Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,44 @@ +# Built application files +*.apk +*.ap_ + +# Files for the ART/Dalvik VM +*.dex + +# Java class files +*.class + +# Generated files +bin/ +gen/ +out/ + +# Gradle files +.gradle/ +build + +# Local configuration file (sdk path, etc) +local.properties + +# Proguard folder generated by Eclipse +proguard/ + +# Log Files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +captures/ + +# Intellij +*.iml +.idea/* + +# Keystore files +*.jks + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.idea/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/CMakeLists.txt Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,30 @@
+#指定CMake的最小版本
+cmake_minimum_required(VERSION 3.4.1)
+
+set(libs_DIR src/main/jniLibs/${ANDROID_ABI})
+
+set(libs_include_DIR src/main/cpp)
+
+#确保 CMake 可以在编译时定位您的标头文件以及源文件
+include_directories(${lib_include_DIR})
+
+link_directories(${libs_DIR})
+
+#添加我们自己的模块,名字是wakeup,SHARED可分享的,以及配置源文件或者头文件的路径
+add_library( wakeup
+ SHARED
+ src/main/cpp/wakeup.cpp
+ src/main/cpp/Interface.h
+ )
+#找到log这个模块
+find_library(log-lib
+ log
+ )
+#把我们自己的模块和动态库bdEASRAndroid模块,找到log这个模块,关联起来
+target_link_libraries(wakeup
+ bdEASRAndroid
+ ${log-lib}
+ )
+
+# 注意:bdEASRAndroid so库不要带版本号 比如:bdEASRAndroid.v1.10.10
+# jniLibs 里面也不要带版本号
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/build.gradle Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,73 @@
+apply plugin: 'com.android.application'
+
+android {
+ compileSdkVersion 25
+ buildToolsVersion "25.0.2"
+ defaultConfig {
+ applicationId "com.baidu.duer.dcs"
+ minSdkVersion 21
+ targetSdkVersion 22
+ versionCode 1
+ versionName "1.0"
+ testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ externalNativeBuild {
+ cmake {
+ cppFlags "-std=c++11 -frtti -fexceptions -I/src/main/cpp"
+ }
+ }
+ ndk {
+ // 平台
+ abiFilters 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'arm64-v8a'
+ }
+ }
+ externalNativeBuild {
+ cmake {
+ path "CMakeLists.txt"
+ }
+ }
+ sourceSets {
+ main {
+ jniLibs.srcDirs = ['src/main/jniLibs']
+ }
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+ }
+ }
+
+ packagingOptions {
+ exclude 'META-INF/DEPENDENCIES.txt'
+ exclude 'META-INF/LICENSE.txt'
+ exclude 'META-INF/NOTICE.txt'
+ exclude 'META-INF/NOTICE'
+ exclude 'META-INF/LICENSE'
+ exclude 'META-INF/DEPENDENCIES'
+ exclude 'META-INF/notice.txt'
+ exclude 'META-INF/license.txt'
+ exclude 'META-INF/dependencies.txt'
+ exclude 'META-INF/LGPL2.1'
+ exclude 'META-INF/ASL2.0'
+ }
+}
+
+dependencies {
+ compile fileTree(include: ['*.jar'], dir: 'libs')
+ androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
+ exclude group: 'com.android.support', module: 'support-annotations'
+ })
+ compile 'com.android.support:appcompat-v7:25.3.0'
+ compile 'com.android.support:design:25.3.0'
+ testCompile 'junit:junit:4.12'
+ compile files('libs/jackson-core-asl-1.9.13.jar')
+ compile files('libs/jackson-mapper-asl-1.9.13.jar')
+ compile files('libs/commons-fileupload-1.3.2.jar')
+ compile files('libs/commons-lang3-3.4.jar')
+ compile files('libs/commons-io-2.5.jar')
+ def okHttp3Version = '3.8.1'
+ compile('com.squareup.okhttp3:okhttp:' + okHttp3Version)
+ compile('com.squareup.okhttp3:logging-interceptor:' + okHttp3Version)
+
+ // debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
+}
Binary file dcs-sdk-java-master/app/libs/commons-fileupload-1.3.2.jar has changed
Binary file dcs-sdk-java-master/app/libs/commons-io-2.5.jar has changed
Binary file dcs-sdk-java-master/app/libs/commons-lang3-3.4.jar has changed
Binary file dcs-sdk-java-master/app/libs/jackson-core-asl-1.9.13.jar has changed
Binary file dcs-sdk-java-master/app/libs/jackson-mapper-asl-1.9.13.jar has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/proguard-rules.pro Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,17 @@
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in D:\AppData\android-sdk-windows/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the proguardFiles
+# directive in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/src/main/AndroidManifest.xml Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,45 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.baidu.duer.dcs"> + + <uses-permission android:name="android.permission.RECORD_AUDIO" /> + <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> + <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.READ_PHONE_STATE"/> + + <application + android:name="com.baidu.duer.dcs.androidapp.DcsSampleApplication" + android:allowBackup="true" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:supportsRtl="true" + android:theme="@style/AppTheme"> + + <activity + android:name="com.baidu.duer.dcs.androidapp.DcsSampleOAuthActivity" + android:label="@string/app_name" + android:screenOrientation="portrait" + android:theme="@style/AppTheme.NoActionBar"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity + android:name="com.baidu.duer.dcs.androidapp.DcsSampleMainActivity" + android:label="@string/app_name" + android:screenOrientation="portrait" + android:theme="@style/AppTheme.NoActionBar" /> + <activity + android:name="com.baidu.duer.dcs.androidapp.DcsSampleScreenHtmlActivity" + android:label="@string/app_name" + android:screenOrientation="portrait" + android:theme="@style/AppTheme.NoActionBar" /> + </application> + +</manifest>
Binary file dcs-sdk-java-master/app/src/main/assets/alarm.mp3 has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/src/main/cpp/Interface.h Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,107 @@ + +#ifndef _EASR_INTERFACE_ +#define _EASR_INTERFACE_ + +int GetEngineVersion(); +int SetLogLevel(int level); +int SetTimeLogFile(const char* fn); +int SetSampleRateMode(int mode); +bool ExistFile(const char* file); +int GetDataDate(const char* fn); +int GetResLine(const char* fn); +int GetResVersion(const char* fn); +bool CheckDataMD5(const char* fn); +int DisableSSE4(); + +int ClearRes(); +int Free(); +int Initial(); +int Initial(const char* dictFile, const char* userFile, const char* mmfFile, const char* hmmMapFile, + short acoustic_model_mode=1,bool fastMode=false); +int BuildNet(int netTreeID,const char* synFile); +int WriteWdNonPron(const char* outFile); + +int BuildSlot(char* buffer,long len); +int ReadSlot(const char* slotFile); +int ReadSlotLink(const char* slotLinkFile); +int ReadLM(const char* lmFn,const char* slotName,bool needBuildSlot); +int LoadRes(const char* lmFn,const char* lmSlotName,const char* slotFile,const char* slotLinkFile); + +int SetVADEndCut(int id,bool vadEdForCut); +int InitialDecoder(int id,int vadID,int nBeam,double prunThres); +int ResetDecoder(int id); +int SetCurrNetTreeID(int id,int treeID,int mode=0); +int Fep(int id,short* data, int dataLen, bool bEd); +int Rec(int id, char** senArr, int expectNum); +char* GetImmeSentence(int id,int& frame); + +char* DecodeAlways(int id,short* data, int dataLen, bool bEd); + +int InitialMem(); +int InitialVAD(int id,float max_speech_len,float max_speech_pause_len); +int ResetVAD(int id); +int VADDetect(int id,short* data, int dataLen, bool bEd); +int GetVadSt(int id); +int GetVadEd(int id); +long int get_dect_end_point_time(int id); + +int KWSSetParam(int type,float value); +int KWSInitial(const char* kwdSynStr,const char* sFile,const char* resDir,int mode = 0); +int KWSReset(int* sceneArr,int n); +int KWSDecode(short* data, int dataLen, char** kwdArr, int expectNum, bool bEd); +int KWSDecode(short* data, int dataLen, char* outJsonStr, bool bEd); +int KWSFree(); + +int AudioSegReset(); +int AudioSegFree(); +int AudioSegInitial(const char* sFile,int mode=0); +int AudioSegDetect(short* data, int dataLen, bool bEd, int& spSt, int& spEd); +int AudioSegDetect(short* data, int dataLen, bool bEd, int& spSt, int& spEd, int *pauseEd); +float AudioSeggetSilConfidence(int contextLen); +int setParam(int function, int type, float value); //function: 1 = audioSeg +int AudioSegGetDelayFrameNum(); + +int WakeUpInitial(const char* wakeUpWd,const char* sFile,int mode=0); +int WakeUpReset(); +int WakeUpDecode(short* data, int dataLen, char** senArr, int expectNum, bool bEd); +int WakeUpDecode(short* data, int dataLen, char** senArr, int expectNum, int &wakeword_frame_len, bool bEd); +int WakeUpDecode(short* data, int dataLen, char** senArr, int expectNum, int &wakeword_frame_len, + bool &is_confidence, int &voice_offset, bool bEd); +int WakeUpFree(); +int WakeUpSetEnvironment(int status);//0 is quiet,else is noise + +int AECInit(); +int AECReset(); +short* AECProcess(short* data_in,short* wav_ref,long len_in); +int AECExit(); + +int GetPyED(const char* str1,const char* str2); +int GetStateED(const char* str1,const char* str2); + +extern char* ChnNameSegPreProcess(const char* aNameArr,const char* aResFileName); +extern char* EngNamePronPreProcess(const char* aNameArr); + +int SetLicenseFlag(bool lic_flag); +bool GetLicenseFlag(); + +#ifdef _ANDROID_ +#include <jni.h> +int GetLicense(JNIEnv *env, jclass obj,jobject context,jstring appCode,jstring cuid,jstring stat,jstring license_file); +int VerifyLicense(JNIEnv *env,jobject context,jstring appCode,jstring cuid,jbyteArray license,jint len,jbyteArray appIDSeq,jstring logDir); +#else +#ifdef _IOS_ +int GetLicense(const char* appCode,const char* stat,const char* license_file); +int VerifyLicense(const char* appCode,const char* license,int len,unsigned int& appID,const char* logDir); +#else //x86 +int GetLicense(const char* appName,const char* appCode,const char* stat,const char* license_file); +int VerifyLicense(const char* appName,const char* appCode,const char* license,int len,unsigned int& appID,const char* logDir); +#endif +#endif +int OpenPVUpload(); +int ClosePVUpload(); +int GetTestAuthorize(); +int GetLongAuthorize(); +bool GetAuthorize(); + + +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/cpp/wakeup.cpp Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.
+ */
+/**
+ * 唤醒调用底层so库实现-jni
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/22.
+ */
+#include <jni.h>
+#include "Interface.h"
+#include <android/log.h>
+
+#define LOG_TAG "wakeup"
+#define LOG_D(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
+
+
+extern "C"
+JNIEXPORT jint JNICALL
+Java_com_baidu_duer_dcs_androidsystemimpl_wakeup_WakeUpNative_wakeUpInitial(JNIEnv *env,
+ jobject instance,
+ jstring wakeUpWd_,
+ jstring sFile_,
+ jint mode) {
+ const char *wakeUpWd = env->GetStringUTFChars(wakeUpWd_, 0);
+ const char *sFile = env->GetStringUTFChars(sFile_, 0);
+
+ int _mode = mode;
+ // 打开log
+ // SetLogLevel(5);
+ LOG_D("WakeUpInitial wakeUpWd=%s", wakeUpWd);
+ LOG_D("WakeUpInitial sFile_=%s", sFile);
+ int ret = WakeUpInitial(wakeUpWd, sFile, _mode);
+ LOG_D("WakeUpInitial ret=%d", ret);
+
+ env->ReleaseStringUTFChars(wakeUpWd_, wakeUpWd);
+ env->ReleaseStringUTFChars(sFile_, sFile);
+
+ return ret;
+}
+
+extern "C"
+JNIEXPORT jint JNICALL
+Java_com_baidu_duer_dcs_androidsystemimpl_wakeup_WakeUpNative_wakeUpReset(JNIEnv *env,
+ jobject instance) {
+ return WakeUpReset();
+}
+
+extern "C"
+JNIEXPORT jint JNICALL
+Java_com_baidu_duer_dcs_androidsystemimpl_wakeup_WakeUpNative_wakeUpDecode(JNIEnv *env,
+ jobject instance,
+ jshortArray data_,
+ jint dataLen,
+ jstring senArr_,
+ jint expectNum,
+ jint wakeWord_frame_len,
+ jboolean is_confidence,
+ jint voice_offset,
+ jboolean bEd) {
+
+
+ jboolean isCopy = 0;
+ short *data_invoke = env->GetShortArrayElements(data_, &isCopy);
+
+ // 写入文件
+ // FILE *file = fopen("/storage/emulated/0/222.pcm", "ab+");
+ // fwrite(data_invoke, sizeof(short) * dataLen, 1, file);
+ // fclose(file);
+
+ LOG_D("WakeUpDecode data_ GetArrayLength=%d", env->GetArrayLength(data_));
+
+ int dataLen_invoke = dataLen;
+ // 因为so库里面最大为2560
+ char *senArr = new char[2560];
+ int expectNum_invoke = expectNum;
+ int wakeWord_frame_len_invoke = wakeWord_frame_len;
+ bool is_confidence_invoke = is_confidence;
+ int voice_offset_invoke = voice_offset;
+ bool bEd_invoke = bEd;
+
+ LOG_D("WakeUpDecode dataLen_invoke=%d", dataLen_invoke);
+ LOG_D("WakeUpDecode expectNum_invoke=%d", expectNum_invoke);
+ LOG_D("WakeUpDecode wakeWord_frame_len_invoke=%d", wakeWord_frame_len_invoke);
+ LOG_D("WakeUpDecode is_confidence_invoke=%d", is_confidence_invoke);
+ LOG_D("WakeUpDecode bEd_invoke=%d", bEd_invoke);
+
+
+ int ret = WakeUpDecode(data_invoke,
+ dataLen_invoke,
+ &senArr,
+ expectNum_invoke,
+ wakeWord_frame_len_invoke,
+ is_confidence_invoke,
+ voice_offset_invoke,
+ bEd_invoke
+ );
+
+ LOG_D("WakeUpDecode ret=%d", ret);
+ LOG_D("WakeUpDecode senArr=%s", senArr);
+ LOG_D("WakeUpDecode wakeWord_frame_len_invoke=%d", wakeWord_frame_len_invoke);
+ LOG_D("WakeUpDecode is_confidence_invoke=%d", is_confidence_invoke);
+ LOG_D("WakeUpDecode voice_offset_invoke=%d", voice_offset_invoke);
+
+ // 释放内存资源
+ env->ReleaseShortArrayElements(data_, data_invoke, 0);
+ env->ReleaseStringUTFChars(senArr_, senArr);
+ return ret;
+}
+
+extern "C"
+JNIEXPORT jint JNICALL
+Java_com_baidu_duer_dcs_androidsystemimpl_wakeup_WakeUpNative_wakeUpFree(JNIEnv *env,
+ jobject instance) {
+ LOG_D("WakeUpFree");
+ return WakeUpFree();
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidapp/DcsSampleApplication.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidapp;
+
+import android.app.Application;
+
+/**
+ * DcsSample application
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/11.
+ */
+public class DcsSampleApplication extends Application {
+ private static volatile DcsSampleApplication instance = null;
+
+ public void onCreate() {
+ super.onCreate();
+ instance = this;
+ // LeakCanary.install(this);
+ }
+
+ public static DcsSampleApplication getInstance() {
+ return instance;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidapp/DcsSampleBaseActivity.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidapp;
+
+import android.app.Activity;
+
+/**
+ * 基础base activity
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/18.
+ */
+public class DcsSampleBaseActivity extends Activity {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidapp/DcsSampleMainActivity.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,395 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidapp;
+
+import android.content.ActivityNotFoundException;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.webkit.WebView;
+import android.widget.Button;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.baidu.duer.dcs.R;
+import com.baidu.duer.dcs.androidsystemimpl.PlatformFactoryImpl;
+import com.baidu.duer.dcs.androidsystemimpl.webview.BaseWebView;
+import com.baidu.duer.dcs.devicemodule.voiceinput.VoiceInputDeviceModule;
+import com.baidu.duer.dcs.framework.DcsFramework;
+import com.baidu.duer.dcs.framework.DeviceModuleFactory;
+import com.baidu.duer.dcs.framework.IResponseListener;
+import com.baidu.duer.dcs.http.HttpConfig;
+import com.baidu.duer.dcs.oauth.api.IOauth;
+import com.baidu.duer.dcs.oauth.api.OauthImpl;
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+import com.baidu.duer.dcs.systeminterface.IPlatformFactory;
+import com.baidu.duer.dcs.systeminterface.IWakeUp;
+import com.baidu.duer.dcs.util.CommonUtil;
+import com.baidu.duer.dcs.util.FileUtil;
+import com.baidu.duer.dcs.util.LogUtil;
+import com.baidu.duer.dcs.util.NetWorkUtil;
+import com.baidu.duer.dcs.wakeup.WakeUp;
+
+import java.io.File;
+
+/**
+ * 主界面 activity
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/18.
+ */
+public class DcsSampleMainActivity extends DcsSampleBaseActivity implements View.OnClickListener {
+ public static final String TAG = "DcsDemoActivity";
+ private Button voiceButton;
+ private TextView textViewTimeStopListen;
+ private Button pauseOrPlayButton;
+ private BaseWebView webView;
+ private LinearLayout mTopLinearLayout;
+ private DcsFramework dcsFramework;
+ private DeviceModuleFactory deviceModuleFactory;
+ private IPlatformFactory platformFactory;
+ private boolean isPause = true;
+ private long startTimeStopListen;
+ private boolean isStopListenReceiving;
+ private String mHtmlUrl;
+ // 唤醒
+ private WakeUp wakeUp;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.dcs_sample_activity_main);
+ initView();
+ initOauth();
+ initFramework();
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ initOauth();
+ }
+
+ private void initView() {
+ Button openLogBtn = (Button) findViewById(R.id.openLogBtn);
+ openLogBtn.setOnClickListener(this);
+ voiceButton = (Button) findViewById(R.id.voiceBtn);
+ voiceButton.setOnClickListener(this);
+
+ textViewTimeStopListen = (TextView) findViewById(R.id.id_tv_time_0);
+ mTopLinearLayout = (LinearLayout) findViewById(R.id.topLinearLayout);
+
+ webView = new BaseWebView(DcsSampleMainActivity.this.getApplicationContext());
+ webView.setWebViewClientListen(new BaseWebView.WebViewClientListener() {
+ @Override
+ public BaseWebView.LoadingWebStatus shouldOverrideUrlLoading(WebView view, String url) {
+ // 拦截处理不让其点击
+ return BaseWebView.LoadingWebStatus.STATUS_TRUE;
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ if (!url.equals(mHtmlUrl) && !"about:blank".equals(mHtmlUrl)) {
+ platformFactory.getWebView().linkClicked(url);
+ }
+
+ mHtmlUrl = url;
+ }
+
+ @Override
+ public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
+
+ }
+ });
+ mTopLinearLayout.addView(webView);
+ webView.loadUrl("about:blank");
+
+ Button mPreviousSongBtn = (Button) findViewById(R.id.previousSongBtn);
+ pauseOrPlayButton = (Button) findViewById(R.id.pauseOrPlayBtn);
+ Button mNextSongBtn = (Button) findViewById(R.id.nextSongBtn);
+ mPreviousSongBtn.setOnClickListener(this);
+ pauseOrPlayButton.setOnClickListener(this);
+ mNextSongBtn.setOnClickListener(this);
+ }
+
+ private void initFramework() {
+ platformFactory = new PlatformFactoryImpl(this);
+ platformFactory.setWebView(webView);
+ dcsFramework = new DcsFramework(platformFactory);
+ deviceModuleFactory = dcsFramework.getDeviceModuleFactory();
+
+ deviceModuleFactory.createVoiceOutputDeviceModule();
+ deviceModuleFactory.createVoiceInputDeviceModule();
+ deviceModuleFactory.getVoiceInputDeviceModule().addVoiceInputListener(
+ new VoiceInputDeviceModule.IVoiceInputListener() {
+ @Override
+ public void onStartRecord() {
+ LogUtil.d(TAG, "onStartRecord");
+ startRecording();
+ }
+
+ @Override
+ public void onFinishRecord() {
+ LogUtil.d(TAG, "onFinishRecord");
+ stopRecording();
+ }
+
+ public void onSucceed(int statusCode) {
+ LogUtil.d(TAG, "onSucceed-statusCode:" + statusCode);
+ if (statusCode != 200) {
+ stopRecording();
+ Toast.makeText(DcsSampleMainActivity.this,
+ getResources().getString(R.string.voice_err_msg),
+ Toast.LENGTH_SHORT)
+ .show();
+ }
+ }
+
+ @Override
+ public void onFailed(String errorMessage) {
+ LogUtil.d(TAG, "onFailed-errorMessage:" + errorMessage);
+ stopRecording();
+ Toast.makeText(DcsSampleMainActivity.this,
+ getResources().getString(R.string.voice_err_msg),
+ Toast.LENGTH_SHORT)
+ .show();
+ }
+ });
+
+ deviceModuleFactory.createAlertsDeviceModule();
+
+ deviceModuleFactory.createAudioPlayerDeviceModule();
+ deviceModuleFactory.getAudioPlayerDeviceModule().addAudioPlayListener(
+ new IMediaPlayer.SimpleMediaPlayerListener() {
+ @Override
+ public void onPaused() {
+ super.onPaused();
+ pauseOrPlayButton.setText(getResources().getString(R.string.audio_paused));
+ isPause = true;
+ }
+
+ @Override
+ public void onPlaying() {
+ super.onPlaying();
+ pauseOrPlayButton.setText(getResources().getString(R.string.audio_playing));
+ isPause = false;
+ }
+
+ @Override
+ public void onCompletion() {
+ super.onCompletion();
+ pauseOrPlayButton.setText(getResources().getString(R.string.audio_default));
+ isPause = false;
+ }
+
+ @Override
+ public void onStopped() {
+ super.onStopped();
+ pauseOrPlayButton.setText(getResources().getString(R.string.audio_default));
+ isPause = true;
+ }
+ });
+
+ deviceModuleFactory.createSystemDeviceModule();
+ deviceModuleFactory.createSpeakControllerDeviceModule();
+ deviceModuleFactory.createPlaybackControllerDeviceModule();
+ deviceModuleFactory.createScreenDeviceModule();
+
+ // init唤醒
+ wakeUp = new WakeUp(platformFactory.getWakeUp(),
+ platformFactory.getAudioRecord());
+ wakeUp.addWakeUpListener(wakeUpListener);
+ // 开始录音,监听是否说了唤醒词
+ wakeUp.startWakeUp();
+ }
+
+ private IWakeUp.IWakeUpListener wakeUpListener = new IWakeUp.IWakeUpListener() {
+ @Override
+ public void onWakeUpSucceed() {
+ Toast.makeText(DcsSampleMainActivity.this,
+ getResources().getString(R.string.wakeup_succeed),
+ Toast.LENGTH_SHORT)
+ .show();
+ voiceButton.performClick();
+ }
+ };
+
+ private void doUserActivity() {
+ deviceModuleFactory.getSystemProvider().userActivity();
+ }
+
+ private void initOauth() {
+ IOauth baiduOauth = new OauthImpl();
+ if (baiduOauth.isSessionValid()) {
+ HttpConfig.setAccessToken(baiduOauth.getAccessToken());
+ } else {
+ baiduOauth.authorize();
+ }
+ }
+
+ private void stopRecording() {
+ wakeUp.startWakeUp();
+ isStopListenReceiving = false;
+ voiceButton.setText(getResources().getString(R.string.stop_record));
+ long t = System.currentTimeMillis() - startTimeStopListen;
+ textViewTimeStopListen.setText(getResources().getString(R.string.time_record, t));
+ }
+
+ private void startRecording() {
+ wakeUp.stopWakeUp();
+ isStopListenReceiving = true;
+ deviceModuleFactory.getSystemProvider().userActivity();
+ voiceButton.setText(getResources().getString(R.string.start_record));
+ textViewTimeStopListen.setText("");
+ }
+
+ @Override
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.voiceBtn:
+ if (!NetWorkUtil.isNetworkConnected(this)) {
+ Toast.makeText(this,
+ getResources().getString(R.string.err_net_msg),
+ Toast.LENGTH_SHORT).show();
+ return;
+ }
+ if (CommonUtil.isFastDoubleClick()) {
+ return;
+ }
+ if (isStopListenReceiving) {
+ platformFactory.getVoiceInput().stopRecord();
+ isStopListenReceiving = false;
+ return;
+ }
+ isStopListenReceiving = true;
+ startTimeStopListen = System.currentTimeMillis();
+ platformFactory.getVoiceInput().startRecord();
+ doUserActivity();
+ break;
+ case R.id.openLogBtn:
+ openAssignFolder(FileUtil.getLogFilePath());
+ break;
+ case R.id.previousSongBtn:
+ platformFactory.getPlayback().previous(nextPreResponseListener);
+ doUserActivity();
+ break;
+ case R.id.nextSongBtn:
+ platformFactory.getPlayback().next(nextPreResponseListener);
+ doUserActivity();
+ break;
+ case R.id.pauseOrPlayBtn:
+ if (isPause) {
+ platformFactory.getPlayback().play(playPauseResponseListener);
+ } else {
+ platformFactory.getPlayback().pause(playPauseResponseListener);
+ }
+ doUserActivity();
+ break;
+ default:
+ break;
+ }
+ }
+
+ private IResponseListener playPauseResponseListener = new IResponseListener() {
+ @Override
+ public void onSucceed(int statusCode) {
+ if (statusCode == 204) {
+ Toast.makeText(DcsSampleMainActivity.this,
+ getResources().getString(R.string.no_directive),
+ Toast.LENGTH_SHORT)
+ .show();
+ }
+ }
+
+ @Override
+ public void onFailed(String errorMessage) {
+ Toast.makeText(DcsSampleMainActivity.this,
+ getResources().getString(R.string.request_error),
+ Toast.LENGTH_SHORT)
+ .show();
+ }
+ };
+
+ private IResponseListener nextPreResponseListener = new IResponseListener() {
+ @Override
+ public void onSucceed(int statusCode) {
+ if (statusCode == 204) {
+ Toast.makeText(DcsSampleMainActivity.this,
+ getResources().getString(R.string.no_audio),
+ Toast.LENGTH_SHORT)
+ .show();
+ }
+ }
+
+ @Override
+ public void onFailed(String errorMessage) {
+ Toast.makeText(DcsSampleMainActivity.this,
+ getResources().getString(R.string.request_error),
+ Toast.LENGTH_SHORT)
+ .show();
+ }
+ };
+
+ /**
+ * 打开日志
+ *
+ * @param path 文件的绝对路径
+ */
+ private void openAssignFolder(String path) {
+ File file = new File(path);
+ if (!file.exists()) {
+ Toast.makeText(DcsSampleMainActivity.this,
+ getResources().getString(R.string.no_log),
+ Toast.LENGTH_SHORT)
+ .show();
+ return;
+ }
+ Intent intent = new Intent(Intent.ACTION_VIEW);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ intent.setDataAndType(Uri.fromFile(file), "text/plain");
+ try {
+ startActivity(Intent.createChooser(intent,
+ getResources().getString(R.string.open_file_title)));
+ } catch (ActivityNotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ // 先remove listener 停止唤醒,释放资源
+ wakeUp.removeWakeUpListener(wakeUpListener);
+ wakeUp.stopWakeUp();
+ wakeUp.releaseWakeUp();
+
+ if (dcsFramework != null) {
+ dcsFramework.release();
+ }
+ webView.setWebViewClientListen(null);
+ mTopLinearLayout.removeView(webView);
+ webView.removeAllViews();
+ webView.destroy();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidapp/DcsSampleOAuthActivity.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidapp;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.text.TextUtils;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.Toast;
+
+import com.baidu.duer.dcs.R;
+import com.baidu.duer.dcs.oauth.api.BaiduDialog;
+import com.baidu.duer.dcs.oauth.api.BaiduDialogError;
+import com.baidu.duer.dcs.oauth.api.BaiduException;
+import com.baidu.duer.dcs.oauth.api.BaiduOauthImplicitGrant;
+import com.baidu.duer.dcs.util.LogUtil;
+
+/**
+ * 用户认证界面
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/18.
+ */
+public class DcsSampleOAuthActivity extends DcsSampleBaseActivity implements View.OnClickListener {
+ // 需要开发者自己申请client_id
+ // client_id,就是oauth的client_id
+ private static final String CLIENT_ID = "{{nc72pRBp2VbSBZk0LSvqHGjFrbjOvQNH}}";
+ // 是否每次授权都强制登陆
+ private boolean isForceLogin = false;
+ // 是否每次都确认登陆
+ private boolean isConfirmLogin = true;
+ private EditText editTextClientId;
+ private Button oauthLoginButton;
+ private BaiduOauthImplicitGrant baiduOauthImplicitGrant;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.dcs_sample_activity_oauth);
+ initView();
+ setOnClickListener();
+ }
+
+ private void setOnClickListener() {
+ oauthLoginButton.setOnClickListener(this);
+ }
+
+ private void initView() {
+ editTextClientId = (EditText) findViewById(R.id.edit_client_id);
+ oauthLoginButton = (Button) findViewById(R.id.btn_login);
+
+ editTextClientId.setText(CLIENT_ID);
+ }
+
+ @Override
+ public void onClick(View view) {
+ switch (view.getId()) {
+ case R.id.btn_login:
+ String clientId = editTextClientId.getText().toString();
+ if (!TextUtils.isEmpty(clientId) && !TextUtils.isEmpty(clientId)) {
+ baiduOauthImplicitGrant = new BaiduOauthImplicitGrant(clientId, DcsSampleOAuthActivity.this.getApplication());
+ baiduOauthImplicitGrant.authorize(DcsSampleOAuthActivity.this, isForceLogin, isConfirmLogin, new BaiduDialog
+ .BaiduDialogListener() {
+ @Override
+ public void onComplete(Bundle values) {
+ Toast.makeText(DcsSampleOAuthActivity.this.getApplicationContext(),
+ getResources().getString(R.string.login_succeed),
+ Toast.LENGTH_SHORT).show();
+ startMainActivity();
+ }
+
+ @Override
+ public void onBaiduException(BaiduException e) {
+
+ }
+
+ @Override
+ public void onError(BaiduDialogError e) {
+ if (null != e) {
+ String toastString = TextUtils.isEmpty(e.getMessage())
+ ? DcsSampleOAuthActivity.this.getResources()
+ .getString(R.string.err_net_msg) : e.getMessage();
+ Toast.makeText(DcsSampleOAuthActivity.this.getApplicationContext(), toastString,
+ Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ @Override
+ public void onCancel() {
+ LogUtil.d("cancle", "I am back");
+ }
+ });
+ } else {
+ Toast.makeText(DcsSampleOAuthActivity.this.getApplicationContext(),
+ getResources().getString(R.string.client_id_empty),
+ Toast.LENGTH_SHORT).show();
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ private void startMainActivity() {
+ Intent intent = new Intent(DcsSampleOAuthActivity.this, DcsSampleMainActivity.class);
+ intent.putExtra("baidu", baiduOauthImplicitGrant);
+ startActivity(intent);
+ finish();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidapp/DcsSampleScreenHtmlActivity.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidapp;
+
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.webkit.WebView;
+import android.widget.RelativeLayout;
+
+import com.baidu.duer.dcs.R;
+import com.baidu.duer.dcs.androidsystemimpl.webview.BaseWebView;
+import com.baidu.duer.dcs.devicemodule.screen.message.HtmlPayload;
+
+/**
+ * show html UI.
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/31.
+ */
+public class DcsSampleScreenHtmlActivity extends DcsSampleBaseActivity {
+ private HtmlPayload htmlPayLoad;
+ private RelativeLayout relativeLayout;
+ private BaseWebView webView;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.dcs_sample_activity_screen_html);
+ htmlPayLoad = (HtmlPayload) this.getIntent().getSerializableExtra("HTML_PLAY_LOAD");
+ initView();
+ addView();
+ }
+
+ private void initView() {
+ relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout);
+ }
+
+ private void addView() {
+ webView = new BaseWebView(DcsSampleScreenHtmlActivity.this.getApplicationContext());
+ webView.setWebViewClientListen(new BaseWebView.WebViewClientListener() {
+ @Override
+ public BaseWebView.LoadingWebStatus shouldOverrideUrlLoading(WebView view, String url) {
+ return BaseWebView.LoadingWebStatus.STATUS_UNKNOW;
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+
+ }
+
+ @Override
+ public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
+
+ }
+ });
+ relativeLayout.addView(webView);
+ if (null != htmlPayLoad) {
+ webView.loadUrl(htmlPayLoad.getUrl());
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/AudioRecordThread.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,84 @@
+/*
+ * *
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl;
+
+import android.media.AudioFormat;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
+
+import com.baidu.duer.dcs.systeminterface.IAudioRecord;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.util.concurrent.LinkedBlockingDeque;
+
+/**
+ * 录音采集线程-音频数据生产者
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/26.
+ */
+public class AudioRecordThread extends Thread implements IAudioRecord {
+ private static final String TAG = AudioRecordThread.class.getSimpleName();
+ // 采样率
+ private static final int SAMPLE_RATE_HZ = 16000;
+ private int bufferSize;
+ private AudioRecord audioRecord;
+ private volatile boolean isStartRecord = false;
+ private LinkedBlockingDeque<byte[]> linkedBlockingDeque;
+
+ public AudioRecordThread(LinkedBlockingDeque<byte[]> linkedBlockingDeque) {
+ this.linkedBlockingDeque = linkedBlockingDeque;
+ bufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE_HZ, AudioFormat.CHANNEL_IN_MONO,
+ AudioFormat.ENCODING_PCM_16BIT);
+ audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_HZ, AudioFormat.CHANNEL_IN_MONO,
+ AudioFormat.ENCODING_PCM_16BIT, bufferSize);
+ }
+
+ @Override
+ public void startRecord() {
+ if (isStartRecord) {
+ return;
+ }
+ isStartRecord = true;
+ this.start();
+ }
+
+ @Override
+ public void stopRecord() {
+ isStartRecord = false;
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ LogUtil.i(TAG, "audioRecord startRecording ");
+ audioRecord.startRecording();
+ byte[] buffer = new byte[bufferSize];
+ while (isStartRecord) {
+ int readBytes = audioRecord.read(buffer, 0, bufferSize);
+ if (readBytes > 0) {
+ linkedBlockingDeque.add(buffer);
+ }
+ }
+ // 清空数据
+ linkedBlockingDeque.clear();
+ // 释放资源
+ audioRecord.stop();
+ audioRecord.release();
+ audioRecord = null;
+ LogUtil.i(TAG, "audioRecord release ");
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/HandlerImpl.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import com.baidu.duer.dcs.systeminterface.IHandler;
+
+/**
+ * Created by wuruisheng on 2017/6/7.
+ */
+public class HandlerImpl implements IHandler {
+ private final Handler handler;
+
+ public HandlerImpl() {
+ handler = new Handler();
+ }
+
+ public HandlerImpl(Looper looper) {
+ handler = new Handler(looper);
+ }
+
+ @Override
+ public boolean post(Runnable runnable) {
+ return handler.post(runnable);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/PlatformFactoryImpl.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl;
+
+import android.content.Context;
+import android.os.Looper;
+
+import com.baidu.duer.dcs.androidsystemimpl.alert.AlertsFileDataStoreImpl;
+import com.baidu.duer.dcs.androidsystemimpl.audioinput.AudioVoiceInputImpl;
+import com.baidu.duer.dcs.androidsystemimpl.playbackcontroller.IPlaybackControllerImpl;
+import com.baidu.duer.dcs.androidsystemimpl.player.MediaPlayerImpl;
+import com.baidu.duer.dcs.androidsystemimpl.wakeup.WakeUpImpl;
+import com.baidu.duer.dcs.systeminterface.IAlertsDataStore;
+import com.baidu.duer.dcs.systeminterface.IAudioInput;
+import com.baidu.duer.dcs.systeminterface.IAudioRecord;
+import com.baidu.duer.dcs.systeminterface.IHandler;
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+import com.baidu.duer.dcs.systeminterface.IPlatformFactory;
+import com.baidu.duer.dcs.systeminterface.IPlaybackController;
+import com.baidu.duer.dcs.systeminterface.IWakeUp;
+import com.baidu.duer.dcs.systeminterface.IWebView;
+
+import java.util.concurrent.LinkedBlockingDeque;
+
+/**
+ * Created by wuruisheng on 2017/6/7.
+ */
+public class PlatformFactoryImpl implements IPlatformFactory {
+ private IHandler mainHandler;
+ private IAudioInput voiceInput;
+ private IWebView webView;
+ private IPlaybackController playback;
+ private Context context;
+ private IAudioRecord audioRecord;
+ private LinkedBlockingDeque<byte[]> linkedBlockingDeque = new LinkedBlockingDeque<>();
+
+ public PlatformFactoryImpl(Context context) {
+ this.context = context.getApplicationContext();
+ }
+
+ @Override
+ public IHandler createHandler() {
+ return new HandlerImpl();
+ }
+
+ @Override
+ public IHandler getMainHandler() {
+ if (mainHandler == null) {
+ mainHandler = new HandlerImpl(Looper.getMainLooper());
+ }
+
+ return mainHandler;
+ }
+
+ @Override
+ public IAudioRecord getAudioRecord() {
+ if (audioRecord == null) {
+ audioRecord = new AudioRecordThread(linkedBlockingDeque);
+ }
+ return audioRecord;
+ }
+
+ @Override
+ public IWakeUp getWakeUp() {
+ return new WakeUpImpl(context, linkedBlockingDeque);
+ }
+
+ @Override
+ public IAudioInput getVoiceInput() {
+ if (voiceInput == null) {
+ voiceInput = new AudioVoiceInputImpl(linkedBlockingDeque);
+ }
+
+ return voiceInput;
+ }
+
+ @Override
+ public IMediaPlayer createMediaPlayer() {
+ return new MediaPlayerImpl();
+ }
+
+ public IAlertsDataStore createAlertsDataStore() {
+ return new AlertsFileDataStoreImpl();
+ }
+
+ @Override
+ public IWebView getWebView() {
+ return webView;
+ }
+
+ @Override
+ public IPlaybackController getPlayback() {
+ if (playback == null) {
+ playback = new IPlaybackControllerImpl();
+ }
+
+ return playback;
+ }
+
+ public void setWebView(IWebView webView) {
+ this.webView = webView;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/alert/AlertsFileDataStoreImpl.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.alert;
+
+import android.os.Handler;
+
+import com.baidu.duer.dcs.devicemodule.alerts.message.Alert;
+import com.baidu.duer.dcs.systeminterface.IAlertsDataStore;
+import com.baidu.duer.dcs.util.CommonUtil;
+import com.baidu.duer.dcs.util.FileUtil;
+import com.baidu.duer.dcs.util.LogUtil;
+import com.baidu.duer.dcs.util.ObjectMapperUtil;
+
+import org.codehaus.jackson.map.ObjectReader;
+import org.codehaus.jackson.map.ObjectWriter;
+import org.codehaus.jackson.type.TypeReference;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * 持久化alert数据到文件-android中实现
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/18.
+ */
+public class AlertsFileDataStoreImpl implements IAlertsDataStore {
+ private static final String TAG = AlertsFileDataStoreImpl.class.getSimpleName();
+ private static final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
+ private Handler mHandler = new Handler();
+
+ public AlertsFileDataStoreImpl() {
+ }
+
+ @Override
+ public void readFromDisk(final IAlertsDataStore.ReadResultListener listener) {
+ mExecutor.execute(new Runnable() {
+ @Override
+ public void run() {
+ FileReader fis;
+ BufferedReader br = null;
+ ObjectReader reader = ObjectMapperUtil.instance()
+ .getObjectReader()
+ .withType(new TypeReference<List<Alert>>() {
+ });
+ try {
+ File file = FileUtil.getAlarmFile();
+ if (file == null) {
+ postReadFailed(listener, "create file failed file is null");
+ return;
+ }
+ fis = new FileReader(file);
+ br = new BufferedReader(fis);
+ List<Alert> alerts = reader.readValue(br);
+ postReadSucceed(listener, alerts);
+ } catch (final FileNotFoundException e) {
+ postReadFailed(listener, "Failed to load alerts from disk.");
+ } catch (IOException e) {
+ postReadFailed(listener, e.getMessage());
+ } finally {
+ CommonUtil.closeQuietly(br);
+ }
+ }
+ });
+ }
+
+ private void postReadFailed(final IAlertsDataStore.ReadResultListener listener, final String errorMessage) {
+ if (listener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onFailed(errorMessage);
+ }
+ });
+ }
+ }
+
+ private void postReadSucceed(final IAlertsDataStore.ReadResultListener listener, final List<Alert> alerts) {
+ if (listener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onSucceed(alerts);
+ }
+ });
+ }
+ }
+
+ @Override
+ public void writeToDisk(final List<Alert> alerts, final IAlertsDataStore.WriteResultListener listener) {
+ mExecutor.execute(new Runnable() {
+
+ @Override
+ public void run() {
+ ObjectWriter writer = ObjectMapperUtil.instance().getObjectWriter();
+ PrintWriter out = null;
+ try {
+ File file = FileUtil.getAlarmFile();
+ if (file == null) {
+ postWriteFailed(listener, "create file failed file is null ");
+ return;
+ }
+ out = new PrintWriter(file);
+ out.print(writer.writeValueAsString(alerts));
+ out.flush();
+ LogUtil.e(TAG, "start postWriteSucceed");
+ postWriteSucceed(listener);
+ } catch (IOException e) {
+ LogUtil.e(TAG, "Failed to write to disk", e);
+ postWriteFailed(listener, "Failed to write to disk,error:" + e.getMessage());
+ } finally {
+ CommonUtil.closeQuietly(out);
+ }
+ }
+ });
+ }
+
+ private void postWriteFailed(final IAlertsDataStore.WriteResultListener listener, final String errorMessage) {
+ if (listener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onFailed(errorMessage);
+ }
+ });
+ }
+ }
+
+ private void postWriteSucceed(final IAlertsDataStore.WriteResultListener listener) {
+ if (listener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onSucceed();
+ }
+ });
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/audioinput/AudioVoiceInputImpl.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,71 @@
+/*
+ * *
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.audioinput;
+
+import android.os.Handler;
+
+import com.baidu.duer.dcs.framework.message.DcsStreamRequestBody;
+import com.baidu.duer.dcs.systeminterface.IAudioInput;
+
+import java.util.concurrent.LinkedBlockingDeque;
+
+/**
+ * AudioInput实现,控制麦克风获取语音数据流
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/26.
+ */
+public class AudioVoiceInputImpl implements IAudioInput {
+ // 消费线程
+ private AudioVoiceInputThread audioVoiceInputThread;
+ // 音频数据
+ private LinkedBlockingDeque<byte[]> linkedBlockingDeque;
+ private IAudioInputListener audioInputListener;
+ private Handler handler = new Handler();
+
+ public AudioVoiceInputImpl(LinkedBlockingDeque<byte[]> linkedBlockingDeque) {
+ this.linkedBlockingDeque = linkedBlockingDeque;
+ }
+
+ @Override
+ public void startRecord() {
+ DcsStreamRequestBody dcsStreamRequestBody = new DcsStreamRequestBody();
+ audioInputListener.onStartRecord(dcsStreamRequestBody);
+ audioVoiceInputThread = new AudioVoiceInputThread(
+ linkedBlockingDeque,
+ dcsStreamRequestBody.sink(),
+ handler);
+ audioVoiceInputThread.setAudioInputListener(new AudioVoiceInputThread.IAudioInputListener() {
+ @Override
+ public void onWriteFinished() {
+ if (audioInputListener != null) {
+ audioInputListener.onStopRecord();
+ }
+ }
+ });
+ audioVoiceInputThread.startWriteStream();
+ }
+
+ @Override
+ public void stopRecord() {
+ audioVoiceInputThread.stopWriteStream();
+ }
+
+ @Override
+ public void registerAudioInputListener(IAudioInputListener audioInputListener) {
+ this.audioInputListener = audioInputListener;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/audioinput/AudioVoiceInputThread.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,131 @@
+/*
+ * *
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.audioinput;
+
+import android.os.Handler;
+
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.io.IOException;
+import java.util.concurrent.LinkedBlockingDeque;
+
+import okio.BufferedSink;
+
+/**
+ * 将语音发送到服务器的线程-发送消费者
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/26.
+ */
+public class AudioVoiceInputThread extends Thread {
+ private static final String TAG = AudioVoiceInputThread.class.getSimpleName();
+ private volatile boolean isStart = false;
+ private BufferedSink bufferedSink;
+ // 音频数据
+ private LinkedBlockingDeque<byte[]> linkedBlockingDeque;
+ private Handler handler;
+
+ public AudioVoiceInputThread(LinkedBlockingDeque<byte[]> linkedBlockingDeque,
+ BufferedSink bufferedSink,
+ Handler handler) {
+ this.linkedBlockingDeque = linkedBlockingDeque;
+ this.bufferedSink = bufferedSink;
+ this.handler = handler;
+ }
+
+ /**
+ * 开始写入数据
+ */
+ public void startWriteStream() {
+ if (isStart) {
+ return;
+ }
+ isStart = true;
+ this.start();
+ }
+
+ /**
+ * 停止写入数据
+ */
+ public void stopWriteStream() {
+ isStart = false;
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ while (isStart) {
+ try {
+ byte[] recordAudioData = linkedBlockingDeque.pollFirst();
+ if (null != recordAudioData) {
+ bufferedSink.write(recordAudioData);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ LogUtil.d(TAG, "writeTo IOException", e);
+ } catch (Exception e) {
+ e.printStackTrace();
+ LogUtil.d(TAG, "writeTo Exception", e);
+ }
+ }
+ if (linkedBlockingDeque.size() > 0) {
+ byte[] recordAudioData = linkedBlockingDeque.pollFirst();
+ if (null != recordAudioData) {
+ LogUtil.d(TAG, "finally writeTo size:" + recordAudioData.length);
+ try {
+ bufferedSink.write(recordAudioData);
+ } catch (IOException e) {
+ e.printStackTrace();
+ LogUtil.d(TAG, " >0 writeTo IOException", e);
+ }
+ }
+ }
+ try {
+ bufferedSink.flush();
+ bufferedSink.close();
+ LogUtil.d(TAG, "closed");
+ } catch (IOException e) {
+ e.printStackTrace();
+ LogUtil.d(TAG, "IOException ", e);
+ }
+ LogUtil.d(TAG, "onWriteFinished ");
+ // 写入完成
+ if (listener != null) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onWriteFinished();
+ }
+ });
+ }
+ }
+
+ private IAudioInputListener listener;
+
+ public void setAudioInputListener(IAudioInputListener listener) {
+ this.listener = listener;
+ }
+
+ /**
+ * 写入完成的回调接口,比如当接收到StopListen指令后回触发
+ */
+ public interface IAudioInputListener {
+ /**
+ * 写入完成后回调此方法
+ */
+ void onWriteFinished();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/playbackcontroller/IPlaybackControllerImpl.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.playbackcontroller;
+
+import com.baidu.duer.dcs.framework.IResponseListener;
+import com.baidu.duer.dcs.systeminterface.IPlaybackController;
+
+/**
+ * 播放控制
+ * <p>
+ * Created by zhoujianliang01@baidu.com on 2017/6/17.
+ */
+public class IPlaybackControllerImpl implements IPlaybackController {
+ private IPlaybackListener playbackListener;
+
+ @Override
+ public void play(IResponseListener responseListener) {
+ if (playbackListener == null) {
+ return;
+ }
+ playbackListener.onPlay(responseListener);
+ }
+
+ @Override
+ public void pause(IResponseListener responseListener) {
+ if (playbackListener == null) {
+ return;
+ }
+ playbackListener.onPause(responseListener);
+ }
+
+ @Override
+ public void previous(IResponseListener responseListener) {
+ if (playbackListener == null) {
+ return;
+ }
+ playbackListener.onPrevious(responseListener);
+ }
+
+ @Override
+ public void next(IResponseListener responseListener) {
+ if (playbackListener == null) {
+ return;
+ }
+ playbackListener.onNext(responseListener);
+ }
+
+ @Override
+ public void registerPlaybackListener(IPlaybackListener listener) {
+ this.playbackListener = listener;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/player/AudioStoreThread.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.player;
+
+import android.os.Handler;
+
+import com.baidu.duer.dcs.util.FileUtil;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * 将stream的mp3流保存到文件中
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/17.
+ */
+public class AudioStoreThread extends Thread {
+ private static final String TAG = AudioStoreThread.class.getSimpleName();
+ private static final int BUFFER_SIZE = 8192;
+ private volatile boolean mThreadExitFlag;
+ private InputStream mInputStream;
+ private Handler mHandler = new Handler();
+
+ private File file;
+ private File completedFile;
+ private FileOutputStream mOutputStream;
+
+ public AudioStoreThread(InputStream is) {
+ this.mInputStream = is;
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ try {
+ file = FileUtil.getSpeakFile();
+ if (file != null) {
+ LogUtil.d(TAG, "AudioStoreThread file: " + file.getAbsolutePath());
+ this.mOutputStream = new FileOutputStream(file);
+ } else {
+ if (mOnDownListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mOnDownListener.onDownError(
+ new JSONObject("AudioStoreThread create temp file failed!"));
+ } catch (JSONException e1) {
+ e1.printStackTrace();
+ }
+ }
+ });
+ }
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ LogUtil.d(TAG, "AudioStoreThread FileNotFoundException ");
+ }
+ if (mOnDownListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mOnDownListener.onDownStart();
+ }
+ });
+ }
+ byte[] audioData = new byte[BUFFER_SIZE];
+ int readBytes;
+ try {
+ while (!mThreadExitFlag && (readBytes = mInputStream.read(audioData)) != -1) {
+ LogUtil.d(TAG, "readBytes=" + readBytes);
+ mOutputStream.write(audioData, 0, readBytes);
+ }
+ mOutputStream.flush();
+ LogUtil.d(TAG, "AudioStoreThread ok ");
+ } catch (final IOException e) {
+ e.printStackTrace();
+ LogUtil.d(TAG, "AudioStoreThread write error ", e);
+ if (mOnDownListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mOnDownListener.onDownError(new JSONObject("AudioStoreThread write error :"
+ + e.getMessage()));
+ } catch (JSONException e1) {
+ e1.printStackTrace();
+ }
+ }
+ });
+ }
+ } finally {
+ try {
+ String fileName = file.getName().substring(0, file.getName().length()
+ - FileUtil.TEMP_POSTFIX.length());
+ LogUtil.d(TAG, "AudioStoreThread fileName : " + fileName);
+ completedFile = new File(file.getParentFile(), fileName);
+ boolean renamed = file.renameTo(completedFile);
+ if (!renamed) {
+ if (mOnDownListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ mOnDownListener.onDownError(new JSONObject("Error renaming file "
+ + file
+ + "to"
+ + completedFile
+ + " for completion!"));
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ }
+ });
+ }
+ }
+ mOutputStream.close();
+ mInputStream.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ if (mOnDownListener != null) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ LogUtil.d(TAG, "completedFile path: " + completedFile.getAbsolutePath());
+ mOnDownListener.onDownComplete(completedFile.getAbsolutePath());
+ }
+ });
+ }
+ }
+ }
+
+ /**
+ * 停止保存/下载
+ */
+ public void stopDown() {
+ LogUtil.d(TAG, "stopDown");
+ mThreadExitFlag = true;
+ mHandler.removeCallbacksAndMessages(null);
+ }
+
+ /**
+ * 删除文件
+ *
+ * @return 是否删除成功
+ */
+ public boolean delDownFile() {
+ LogUtil.d(TAG, "delDownFile");
+ if (completedFile != null && completedFile.exists()) {
+ return completedFile.delete();
+ }
+ return false;
+ }
+
+ public static class SimpleOnDownListener implements OnDownListener {
+ @Override
+ public void onDownStart() {
+ }
+
+ @Override
+ public void onDownComplete(String path) {
+ }
+
+ @Override
+ public void onDownError(JSONObject jsonObject) {
+ }
+ }
+
+ public OnDownListener mOnDownListener;
+
+ public void setOnDownListener(OnDownListener listener) {
+ this.mOnDownListener = listener;
+ }
+
+ /**
+ * 流保存回调接口
+ */
+ public interface OnDownListener {
+ void onDownStart();
+
+ void onDownComplete(String path);
+
+ void onDownError(JSONObject jsonObject);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/player/AudioStreamStoreImpl.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.player;
+
+import org.json.JSONObject;
+
+import java.io.InputStream;
+
+/**
+ * 保存音频mp3流到文件中-android中实现
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/1.
+ */
+public class AudioStreamStoreImpl implements IAudioStreamStore {
+ private AudioStoreThread mAudioStoreThread;
+ private OnStoreListener onStoreListener;
+
+ @Override
+ public void save(InputStream inputStream) {
+ mAudioStoreThread = new AudioStoreThread(inputStream);
+ mAudioStoreThread.setOnDownListener(simpleOnDownListener);
+ mAudioStoreThread.start();
+ }
+
+ @Override
+ public void cancel() {
+ if (mAudioStoreThread != null) {
+ mAudioStoreThread.stopDown();
+ }
+ }
+
+ @Override
+ public void speakAfter() {
+ if (mAudioStoreThread != null) {
+ mAudioStoreThread.delDownFile();
+ }
+ }
+
+ @Override
+ public void setOnStoreListener(OnStoreListener listener) {
+ onStoreListener = listener;
+ }
+
+ private AudioStoreThread.SimpleOnDownListener simpleOnDownListener = new AudioStoreThread.SimpleOnDownListener() {
+ @Override
+ public void onDownComplete(String path) {
+ super.onDownComplete(path);
+ if (onStoreListener != null) {
+ onStoreListener.onComplete(path);
+ }
+ }
+
+ @Override
+ public void onDownError(JSONObject jsonObject) {
+ super.onDownError(jsonObject);
+ if (onStoreListener != null) {
+ onStoreListener.onError(jsonObject.toString());
+ }
+ }
+ };
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/player/IAudioStreamStore.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.player;
+
+import java.io.InputStream;
+
+/**
+ * mp3流保存接口
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/1.
+ */
+public interface IAudioStreamStore {
+ /**
+ * 保存mp3流到文件中(存储设备中)
+ */
+ void save(InputStream inputStream);
+
+ /**
+ * 取消保存
+ */
+ void cancel();
+
+ /**
+ * 播报完成后处理的操作,比如删除保存的文件
+ */
+ void speakAfter();
+
+ /**
+ * 保存回调监听
+ *
+ * @param listener listener
+ */
+ void setOnStoreListener(OnStoreListener listener);
+
+ /**
+ * 保存回调接口
+ */
+ interface OnStoreListener {
+ void onStart();
+
+ void onComplete(String path);
+
+ void onError(String errorMessage);
+ }
+
+ class SimpleOnStoreListener implements OnStoreListener {
+ @Override
+ public void onStart() {
+ }
+
+ @Override
+ public void onComplete(String path) {
+ }
+
+ @Override
+ public void onError(String errorMessage) {
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/player/MediaPlayerImpl.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.player;
+
+import android.app.Service;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.AssetManager;
+import android.media.AudioManager;
+import android.media.MediaPlayer;
+import android.telephony.PhoneStateListener;
+import android.telephony.TelephonyManager;
+import android.text.TextUtils;
+
+import com.baidu.duer.dcs.androidapp.DcsSampleApplication;
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * android MediaPlayer -android平台中实现音频的播放逻辑
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/31.
+ */
+public class MediaPlayerImpl implements IMediaPlayer {
+ private static final String TAG = MediaPlayerImpl.class.getSimpleName();
+ public static final String ASSERT_PREFIX = "assets://";
+ private static final String KEY_SP_VOLUME = "currentVolume";
+ private static final String KEY_SP_MUTE = "isMute";
+ private IMediaPlayer.PlayState mCurrentState = IMediaPlayer.PlayState.IDLE;
+ private MediaPlayer mMediaPlayer;
+ private float currentVolume = 0.8f; // 默认音量80%
+ private boolean isMute;
+ private boolean isError38;
+ private float currentPercent;
+ private int currentSeekMilliseconds;
+ private IAudioStreamStore audioStreamStore; // stream流数据保存
+ private List<IMediaPlayer.IMediaPlayerListener> mediaPlayerListeners;
+ private boolean isActive;
+ private TelephonyManager telephonyManager;
+
+ public MediaPlayerImpl() {
+ mMediaPlayer = new MediaPlayer();
+ // set audio stream type
+ mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
+ mMediaPlayer.setOnBufferingUpdateListener(bufferingUpdateListener);
+ mMediaPlayer.setOnErrorListener(errorListener);
+ mMediaPlayer.setOnPreparedListener(preparedListener);
+ mMediaPlayer.setOnCompletionListener(completionListener);
+ mMediaPlayer.setOnSeekCompleteListener(seekCompleteListener);
+ // 不同的音频源,此回调有的不回调!!!
+ // mMediaPlayer.setOnInfoListener(infoListener);
+
+ // 读取音量和静音的数据
+ currentVolume = (float) MediaPlayerPreferenceUtil.get(DcsSampleApplication.getInstance(),
+ KEY_SP_VOLUME, 0.8f);
+ isMute = (boolean) MediaPlayerPreferenceUtil.get(DcsSampleApplication.getInstance(),
+ KEY_SP_MUTE, false);
+ // LinkedList
+ mediaPlayerListeners = Collections.synchronizedList(new LinkedList<IMediaPlayer.IMediaPlayerListener>());
+
+ // 来电监听
+ telephonyManager = (TelephonyManager)
+ DcsSampleApplication.getInstance().getSystemService(Service.TELEPHONY_SERVICE);
+ telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
+ }
+
+ private PhoneStateListener phoneStateListener = new PhoneStateListener() {
+ @Override
+ public void onCallStateChanged(int state, String incomingNumber) {
+ super.onCallStateChanged(state, incomingNumber);
+ switch (state) {
+ // 电话挂断
+ case TelephonyManager.CALL_STATE_IDLE:
+ resume();
+ break;
+ // 等待接电话
+ case TelephonyManager.CALL_STATE_RINGING:
+ pause();
+ break;
+ // 通话中
+ case TelephonyManager.CALL_STATE_OFFHOOK:
+ break;
+ default:
+ break;
+ }
+ }
+ };
+
+ private IAudioStreamStore.OnStoreListener onStoreListener = new IAudioStreamStore.SimpleOnStoreListener() {
+ @Override
+ public void onComplete(String path) {
+ LogUtil.e(TAG, "onStoreListener,path:" + path);
+ // after down star play
+ File file = new File(path);
+ if (file.exists() && file.length() > 0) {
+ play(path);
+ } else {
+ mCurrentState = IMediaPlayer.PlayState.ERROR;
+ fireOnError("play path not exists or length<0 ",
+ IMediaPlayer.ErrorType.MEDIA_ERROR_INTERNAL_DEVICE_ERROR);
+ }
+ }
+ };
+
+ @Override
+ public void play(MediaResource mediaResource) {
+ if (mediaResource.isStream) {
+ play(mediaResource.stream);
+ } else {
+ play(mediaResource.url);
+ }
+ }
+
+ private void play(InputStream stream) {
+ LogUtil.e(TAG, "play stream");
+ if (audioStreamStore == null) {
+ audioStreamStore = new AudioStreamStoreImpl();
+ }
+ audioStreamStore.setOnStoreListener(onStoreListener);
+ audioStreamStore.save(stream);
+ }
+
+ private void play(String url) {
+ if (TextUtils.isEmpty(url)) {
+ LogUtil.d(TAG, "play-url is empty");
+ fireOnError("play-url is empty.",
+ IMediaPlayer.ErrorType.MEDIA_ERROR_INTERNAL_DEVICE_ERROR);
+ mCurrentState = IMediaPlayer.PlayState.ERROR;
+ return;
+ }
+ fireOnInit();
+ LogUtil.d(TAG, "play-url:" + url);
+ if (url.startsWith(ASSERT_PREFIX) && url.length() > ASSERT_PREFIX.length()) {
+ playAsset(url.substring(ASSERT_PREFIX.length()));
+ } else {
+ try {
+ mMediaPlayer.reset();
+ mMediaPlayer.setDataSource(url);
+ // Async
+ mMediaPlayer.prepareAsync();
+ mCurrentState = IMediaPlayer.PlayState.PREPARING;
+ } catch (IOException e) {
+ e.printStackTrace();
+ LogUtil.d(TAG, "playPath", e);
+ mCurrentState = IMediaPlayer.PlayState.ERROR;
+ fireOnError("IOException play url :"
+ + url, IMediaPlayer.ErrorType.MEDIA_ERROR_INTERNAL_DEVICE_ERROR);
+ }
+ }
+ }
+
+ private void playAsset(String resName) {
+ LogUtil.d(TAG, "playAsset:" + resName);
+ try {
+ AssetManager am = DcsSampleApplication.getInstance().getAssets();
+ AssetFileDescriptor afd = am.openFd(resName);
+ mMediaPlayer.reset();
+ mMediaPlayer.setDataSource(afd.getFileDescriptor(),
+ afd.getStartOffset(), afd.getLength());
+ mMediaPlayer.prepareAsync();
+ mCurrentState = IMediaPlayer.PlayState.PREPARING;
+ } catch (IOException e) {
+ e.printStackTrace();
+ LogUtil.d(TAG, "playAsset", e);
+ mCurrentState = IMediaPlayer.PlayState.ERROR;
+ fireOnError("IOException play playAsset",
+ IMediaPlayer.ErrorType.MEDIA_ERROR_INTERNAL_DEVICE_ERROR);
+ }
+ }
+
+ @Override
+ public void pause() {
+ if (mCurrentState == IMediaPlayer.PlayState.PLAYING
+ || mCurrentState == IMediaPlayer.PlayState.PREPARED
+ || mCurrentState == IMediaPlayer.PlayState.PREPARING) {
+ mMediaPlayer.pause();
+ mCurrentState = IMediaPlayer.PlayState.PAUSED;
+ fireOnPaused();
+ }
+ }
+
+ @Override
+ public void stop() {
+ if (mMediaPlayer != null) {
+ mMediaPlayer.stop();
+ mCurrentState = IMediaPlayer.PlayState.STOPPED;
+ // delete audio file
+ if (audioStreamStore != null) {
+ audioStreamStore.cancel();
+ audioStreamStore.speakAfter();
+ }
+ fireStopped();
+ }
+ }
+
+
+ @Override
+ public void resume() {
+ if (mCurrentState == IMediaPlayer.PlayState.PAUSED) {
+ mMediaPlayer.start();
+ mCurrentState = IMediaPlayer.PlayState.PLAYING;
+ firePlaying();
+ }
+ }
+
+ @Override
+ public void release() {
+ if (mMediaPlayer != null) {
+ mMediaPlayer.stop();
+ mMediaPlayer.release();
+ mMediaPlayer = null;
+ mCurrentState = IMediaPlayer.PlayState.IDLE;
+ fireOnRelease();
+ }
+ if (audioStreamStore != null) {
+ audioStreamStore.cancel();
+ audioStreamStore.speakAfter();
+ }
+ mediaPlayerListeners.clear();
+ }
+
+ @Override
+ public PlayState getPlayState() {
+ return mCurrentState;
+ }
+
+ @Override
+ public void seekTo(int pos) {
+ currentSeekMilliseconds = pos;
+ LogUtil.d(TAG, "seekTo,currentSeekMilliseconds:" + currentSeekMilliseconds);
+ if (mMediaPlayer != null && mCurrentState == IMediaPlayer.PlayState.PREPARED) {
+ mMediaPlayer.seekTo(pos);
+ }
+ }
+
+ /**
+ * 设置音量
+ *
+ * @param volume 0.0 -1.0
+ */
+ @Override
+ public void setVolume(float volume) {
+ // 设置音量就不再静音了,比如:说了调衡音量等操作
+ isMute = false;
+ currentVolume = volume;
+ if (mMediaPlayer != null) {
+ mMediaPlayer.setVolume(volume, volume);
+ }
+ // 保存数据
+ MediaPlayerPreferenceUtil.put(DcsSampleApplication.getInstance(),
+ KEY_SP_VOLUME, currentVolume);
+ MediaPlayerPreferenceUtil.put(DcsSampleApplication.getInstance(),
+ KEY_SP_MUTE, isMute);
+ }
+
+ @Override
+ public float getVolume() {
+ return currentVolume;
+ }
+
+ @Override
+ public void setMute(boolean mute) {
+ isMute = mute;
+ if (mMediaPlayer != null) {
+ if (mute) {
+ mMediaPlayer.setVolume(0, 0);
+ } else {
+ mMediaPlayer.setVolume(currentVolume, currentVolume);
+ }
+ }
+ // 保存数据
+ MediaPlayerPreferenceUtil.put(DcsSampleApplication.getInstance(),
+ KEY_SP_MUTE, isMute);
+ }
+
+ @Override
+ public boolean getMute() {
+ return isMute;
+ }
+
+ @Override
+ public long getCurrentPosition() {
+ if (mMediaPlayer == null) {
+ return 0;
+ }
+ if (mCurrentState == IMediaPlayer.PlayState.IDLE || mCurrentState == IMediaPlayer.PlayState.ERROR) {
+ return 0;
+ }
+ return mMediaPlayer.getCurrentPosition();
+ }
+
+ @Override
+ public long getDuration() {
+ if (mMediaPlayer == null) {
+ return 0;
+ }
+ if (mCurrentState == IMediaPlayer.PlayState.IDLE || mCurrentState == IMediaPlayer.PlayState.ERROR) {
+ return 0;
+ }
+ return mMediaPlayer.getDuration();
+ }
+
+ @Override
+ public float getBufferPercentage() {
+ return currentPercent;
+ }
+
+
+ @Override
+ public void addMediaPlayerListener(IMediaPlayerListener listener) {
+ if (!mediaPlayerListeners.contains(listener)) {
+ mediaPlayerListeners.add(listener);
+ }
+ }
+
+ @Override
+ public void removeMediaPlayerListener(IMediaPlayerListener listener) {
+ if (mediaPlayerListeners.contains(listener)) {
+ mediaPlayerListeners.remove(listener);
+ }
+ }
+
+ @Override
+ public void setActive(boolean isActive) {
+ this.isActive = isActive;
+ }
+
+ @Override
+ public boolean isActive() {
+ return isActive;
+ }
+
+ private void fireOnError(String error, ErrorType errorType) {
+ for (IMediaPlayer.IMediaPlayerListener listener : mediaPlayerListeners) {
+ if (listener != null) {
+ listener.onError(error, errorType);
+ }
+ }
+ }
+
+ private void fireOnInit() {
+ for (IMediaPlayer.IMediaPlayerListener listener : mediaPlayerListeners) {
+ if (listener != null) {
+ listener.onInit();
+ }
+ }
+ }
+
+ private void fireOnPaused() {
+ for (IMediaPlayer.IMediaPlayerListener listener : mediaPlayerListeners) {
+ if (listener != null) {
+ listener.onPaused();
+ }
+ }
+ }
+
+ private void fireStopped() {
+ for (IMediaPlayer.IMediaPlayerListener listener : mediaPlayerListeners) {
+ if (listener != null) {
+ listener.onStopped();
+ }
+ }
+ }
+
+ private void firePlaying() {
+ for (IMediaPlayer.IMediaPlayerListener listener : mediaPlayerListeners) {
+ if (listener != null) {
+ listener.onPlaying();
+ }
+ }
+ }
+
+ private void fireOnRelease() {
+ for (IMediaPlayer.IMediaPlayerListener listener : mediaPlayerListeners) {
+ if (listener != null) {
+ listener.onRelease();
+ }
+ }
+ }
+
+ private void fireOnPrepared() {
+ for (IMediaPlayer.IMediaPlayerListener listener : mediaPlayerListeners) {
+ if (listener != null) {
+ listener.onPrepared();
+ }
+ }
+ }
+
+ private void fireOonBufferingUpdate(int percent) {
+ for (IMediaPlayer.IMediaPlayerListener listener : mediaPlayerListeners) {
+ if (listener != null) {
+ listener.onBufferingUpdate(percent);
+ }
+ }
+ }
+
+ private void fireOnCompletion() {
+ for (IMediaPlayer.IMediaPlayerListener listener : mediaPlayerListeners) {
+ if (listener != null) {
+ listener.onCompletion();
+ }
+ }
+ }
+
+ private MediaPlayer.OnPreparedListener preparedListener = new MediaPlayer.OnPreparedListener() {
+ @Override
+ public void onPrepared(MediaPlayer mp) {
+ LogUtil.d(TAG, "onPrepared");
+ mCurrentState = IMediaPlayer.PlayState.PREPARED;
+ isError38 = false;
+ fireOnPrepared();
+ // must be called after prepareAsync or prepare
+ LogUtil.d(TAG, "currentVolume:" + currentVolume);
+ LogUtil.d(TAG, "currentSeekMilliseconds:" + currentSeekMilliseconds);
+ // 一开始就说话让它静音了
+ if (isMute) {
+ mMediaPlayer.setVolume(0, 0);
+ } else {
+ setVolume(currentVolume);
+ }
+ seekTo(currentSeekMilliseconds);
+ }
+ };
+
+ private MediaPlayer.OnBufferingUpdateListener bufferingUpdateListener =
+ new MediaPlayer.OnBufferingUpdateListener() {
+ @Override
+ public void onBufferingUpdate(MediaPlayer mp, int percent) {
+ currentPercent = percent * 1.0f;
+ fireOonBufferingUpdate(percent);
+ }
+ };
+ private MediaPlayer.OnErrorListener errorListener = new MediaPlayer.OnErrorListener() {
+ @Override
+ public boolean onError(MediaPlayer mp, int what, int extra) {
+ LogUtil.d(TAG, "onError:" + what + ", extra:" + extra);
+ if (what == -38) {
+ isError38 = true;
+ return false;
+ }
+ isError38 = false;
+ mCurrentState = IMediaPlayer.PlayState.ERROR;
+ JSONObject jsonObject = new JSONObject();
+ try {
+ jsonObject.put("msg", "what: " + what + "; extra:" + extra);
+ } catch (JSONException e) {
+ e.printStackTrace();
+ }
+ IMediaPlayer.ErrorType errorType;
+ switch (what) {
+ case MediaPlayer.MEDIA_ERROR_IO:
+ // Stream服务端返回错误 (bad request, unauthorized, forbidden, not found etc)
+ errorType = IMediaPlayer.ErrorType.MEDIA_ERROR_INVALID_REQUEST;
+ break;
+ case MediaPlayer.MEDIA_ERROR_TIMED_OUT:
+ // 端无法连接stream服务端
+ errorType = IMediaPlayer.ErrorType.MEDIA_ERROR_SERVICE_UNAVAILABLE;
+ break;
+ case MediaPlayer.MEDIA_ERROR_UNSUPPORTED:
+ // 端内部错误
+ errorType = IMediaPlayer.ErrorType.MEDIA_ERROR_INTERNAL_DEVICE_ERROR;
+ break;
+ case MediaPlayer.MEDIA_ERROR_MALFORMED:
+ // stream服务端接受请求,但未能正确处理 ?????
+ errorType = IMediaPlayer.ErrorType.MEDIA_ERROR_INTERNAL_SERVER_ERROR;
+ break;
+ default:
+ // 未知错误
+ errorType = IMediaPlayer.ErrorType.MEDIA_ERROR_UNKNOWN;
+ break;
+ }
+ fireOnError(jsonObject.toString(), errorType);
+ return false;
+ }
+ };
+
+ private MediaPlayer.OnSeekCompleteListener seekCompleteListener = new MediaPlayer.OnSeekCompleteListener() {
+ @Override
+ public void onSeekComplete(MediaPlayer mp) {
+ LogUtil.d(TAG, "onSeekComplete");
+ if (mCurrentState == IMediaPlayer.PlayState.PREPARED) {
+ mp.start();
+ mCurrentState = IMediaPlayer.PlayState.PLAYING;
+ firePlaying();
+ }
+ }
+ };
+
+ private MediaPlayer.OnCompletionListener completionListener = new MediaPlayer.OnCompletionListener() {
+ @Override
+ public void onCompletion(MediaPlayer mp) {
+ if (isError38) {
+ return;
+ }
+ LogUtil.d(TAG, "onCompletion");
+ // delete audio file
+ if (audioStreamStore != null) {
+ audioStreamStore.cancel();
+ audioStreamStore.speakAfter();
+ }
+ mCurrentState = IMediaPlayer.PlayState.COMPLETED;
+ fireOnCompletion();
+ }
+ };
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/player/MediaPlayerPreferenceUtil.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.player;
+
+import android.content.Context;
+
+import com.baidu.duer.dcs.util.PreferenceUtil;
+
+/**
+ * Media Player 保存音量和静音的状态
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/17.
+ */
+public class MediaPlayerPreferenceUtil extends PreferenceUtil {
+ // 保存到的文件名字
+ private static final String BAIDU_MEDIA_CONFIG = "baidu_media_config";
+
+ /**
+ * 保存音量或者静音的数据状态
+ *
+ * @param context 上下文
+ * @param key 键
+ * @param object 值
+ */
+ public static void put(Context context, String key, Object object) {
+ put(context, BAIDU_MEDIA_CONFIG, key, object);
+ }
+
+ /**
+ * 读取音量或者静音的数据状态
+ *
+ * @param context 上下文
+ * @param key 键
+ * @param defaultObject 默认值
+ */
+ public static Object get(Context context, String key, Object defaultObject) {
+ return get(context, BAIDU_MEDIA_CONFIG, key, defaultObject);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/wakeup/WakeUpDecodeThread.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,225 @@
+/*
+ * *
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.wakeup;
+
+import android.os.Handler;
+
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.util.concurrent.LinkedBlockingDeque;
+
+/**
+ * 唤醒声音处理-唤醒消费者
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/22.
+ */
+public class WakeUpDecodeThread extends Thread {
+ private static final String TAG = WakeUpDecodeThread.class.getSimpleName();
+ // 唤醒成功
+ private static final int WAKEUP_SUCCEED = 1;
+ // 唤醒词位置
+ private int voiceOffset;
+ private boolean isWakeUp;
+ private WakeUpNative wakeUpNative;
+ private Handler handler;
+ private volatile boolean isStart = false;
+ private LinkedBlockingDeque<byte[]> linkedBlockingDeque;
+
+ public WakeUpDecodeThread(LinkedBlockingDeque<byte[]> linkedBlockingDeque,
+ WakeUpNative wakeUpNative,
+ Handler handler) {
+ this.linkedBlockingDeque = linkedBlockingDeque;
+ this.wakeUpNative = wakeUpNative;
+ this.handler = handler;
+ }
+
+ /**
+ * 开始唤醒
+ */
+ public void startWakeUp() {
+ if (isStart) {
+ return;
+ }
+ isStart = true;
+ this.start();
+ }
+
+ public boolean isStart() {
+ return isStart;
+ }
+
+ /**
+ * 停止唤醒
+ */
+ public void stopWakeUp() {
+ isStart = false;
+ }
+
+ @Override
+ public void run() {
+ super.run();
+ LogUtil.i(TAG, "wakeup wakeUpDecode start" );
+ while (isStart) {
+ try {
+ byte[] data = linkedBlockingDeque.take();
+
+ // 暂时不检测vad
+ // int volume = calculateVolume(data, 16);
+ // LogUtil.i(TAG, "wakeup audioRecord Volume:" + volume);
+ // if (volume <= 0) {
+ // continue;
+ // }
+
+ if (data.length > 0) {
+ // 是否为最后一帧数据
+ boolean isEnd = false;
+ short[] arr = byteArray2ShortArray(data, data.length / 2);
+ int ret = wakeUpNative.wakeUpDecode(
+ arr,
+ arr.length,
+ "",
+ 1,
+ -1,
+ true,
+ voiceOffset++,
+ isEnd
+ );
+ // 唤醒成功
+ if (ret == WAKEUP_SUCCEED) {
+ LogUtil.i(TAG, "wakeup wakeUpDecode ret:" + ret);
+ isWakeUp = true;
+ stopWakeUp();
+ LogUtil.i(TAG, "wakeup wakeUpDecode succeed !!");
+ break;
+ }
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ LogUtil.i(TAG, "wakeup after wakeUpDecode over !!");
+ LogUtil.i(TAG, "wakeup after linkedBlockingDeque size:" + linkedBlockingDeque.size());
+
+ if (isWakeUp) {
+ if (listener != null) {
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ listener.onWakeUpSucceed();
+ }
+ });
+ }
+ }
+ // 重置
+ voiceOffset = 0;
+ isWakeUp = false;
+ }
+
+ /**
+ * 将byte数组转为short数组
+ *
+ * @param data byte数组的音频数据
+ * @param items short数组的大小
+ * @return 转换后的short数组
+ */
+ private short[] byteArray2ShortArray(byte[] data, int items) {
+ short[] retVal = new short[items];
+ for (int i = 0; i < retVal.length; i++) {
+ retVal[i] = (short) ((data[i * 2] & 0xff) | (data[i * 2 + 1] & 0xff) << 8);
+ }
+ return retVal;
+ }
+
+ /**
+ * 根据输入的音量大小来判断用户是否有语音输入
+ *
+ * @param var0 原始音频数据
+ * @param var1 音频数据格式位PCM,16位每个样本,比如如果音频数据格式设为AudioFormat.ENCODING_PCM_16BIT,则参数传16
+ * @return >0 代表有音频输入
+ */
+ private int calculateVolume(byte[] var0, int var1) {
+ int[] var3 = null;
+ int var4 = var0.length;
+ int var2;
+ if (var1 == 8) {
+ var3 = new int[var4];
+ for (var2 = 0; var2 < var4; ++var2) {
+ var3[var2] = var0[var2];
+ }
+ } else if (var1 == 16) {
+ var3 = new int[var4 / 2];
+ for (var2 = 0; var2 < var4 / 2; ++var2) {
+ byte var5 = var0[var2 * 2];
+ byte var6 = var0[var2 * 2 + 1];
+ int var13;
+ if (var5 < 0) {
+ var13 = var5 + 256;
+ } else {
+ var13 = var5;
+ }
+ short var7 = (short) (var13 + 0);
+ if (var6 < 0) {
+ var13 = var6 + 256;
+ } else {
+ var13 = var6;
+ }
+ var3[var2] = (short) (var7 + (var13 << 8));
+ }
+ }
+ int[] var8 = var3;
+ if (var3 != null && var3.length != 0) {
+ float var10 = 0.0F;
+ for (int var11 = 0; var11 < var8.length; ++var11) {
+ var10 += (float) (var8[var11] * var8[var11]);
+ }
+ var10 /= (float) var8.length;
+ float var12 = 0.0F;
+ for (var4 = 0; var4 < var8.length; ++var4) {
+ var12 += (float) var8[var4];
+ }
+ var12 /= (float) var8.length;
+ var4 = (int) (Math.pow(2.0D, (double) (var1 - 1)) - 1.0D);
+ double var14 = Math.sqrt((double) (var10 - var12 * var12));
+ int var9;
+ if ((var9 = (int) (10.0D * Math.log10(var14 * 10.0D * Math.sqrt(2.0D) / (double) var4 + 1.0D))) < 0) {
+ var9 = 0;
+ }
+ if (var9 > 10) {
+ var9 = 10;
+ }
+ return var9;
+ } else {
+ return 0;
+ }
+ }
+
+ private IWakeUpListener listener;
+
+ public void setWakeUpListener(IWakeUpListener listener) {
+ this.listener = listener;
+ }
+
+ /**
+ * 唤醒成功回调接口
+ */
+ public interface IWakeUpListener {
+ /**
+ * 唤醒成功后回调
+ */
+ void onWakeUpSucceed();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/wakeup/WakeUpImpl.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,132 @@
+/*
+ * *
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.wakeup;
+
+import android.content.Context;
+import android.os.Handler;
+
+import com.baidu.duer.dcs.systeminterface.IWakeUp;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.LinkedBlockingDeque;
+
+/**
+ * 唤醒模块-android中实现
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/25.
+ */
+public class WakeUpImpl implements IWakeUp {
+ private static final String TAG = WakeUpImpl.class.getSimpleName();
+ // 初始化唤醒词成功
+ private static final int WAKEUP_INIT_SUCCEED = 0;
+ // 唤醒词
+ private static final String WAKEUP_WORD = "小度小度";
+ // 唤醒词声学模型模型文件
+ private static final String WAKEUP_FILENAME = "libbdEasrS1MergeNormal.so";
+ // jni
+ private WakeUpNative wakeUpNative;
+ // Decode消费线程
+ private WakeUpDecodeThread wakeUpDecodeThread;
+ // callback
+ private List<IWakeUpListener> wakeUpListeners;
+ private Handler handler = new Handler();
+ // 音频数据
+ private LinkedBlockingDeque<byte[]> linkedBlockingDeque;
+ // 初始化唤醒词的返回值
+ private int wakeUpInitialRet;
+ private Context context;
+
+ public WakeUpImpl(Context context, LinkedBlockingDeque<byte[]> linkedBlockingDeque) {
+ this.linkedBlockingDeque = linkedBlockingDeque;
+ this.context = context.getApplicationContext();
+ this.wakeUpNative = new WakeUpNative();
+ this.wakeUpListeners = Collections.synchronizedList(new LinkedList<IWakeUpListener>());
+ this.initWakeUp();
+ }
+
+ private void initWakeUp() {
+ // 方法1:加载声学模型文件,当作so库进行加载到nativeLibraryDir目录中
+ // 方法2:当然你也可以放到assets目录或者raw下,然后进行拷贝到应用的私有目录或者sd卡
+ // 方法2需要处理声学模型文件覆盖安装问题,以及不可预料的拷贝失败问题!
+ String path = this.context.getApplicationInfo().nativeLibraryDir
+ + File.separatorChar + WAKEUP_FILENAME;
+ LogUtil.d(TAG, "wakeup path:" + path);
+ LogUtil.d(TAG, "wakeup exists:" + new File(path).exists());
+ // 1.初始化唤醒词,0 是初始化成功
+ wakeUpInitialRet = wakeUpNative.wakeUpInitial(WAKEUP_WORD, path, 0);
+ LogUtil.d(TAG, "wakeUpInitialRet:" + wakeUpInitialRet);
+ }
+
+ @Override
+ public void startWakeUp() {
+ if (wakeUpDecodeThread != null && wakeUpDecodeThread.isStart()) {
+ LogUtil.d(TAG, "wakeup wakeUpDecodeThread is Started !");
+ return;
+ }
+ // 2.开始唤醒
+ if (wakeUpInitialRet == WAKEUP_INIT_SUCCEED) {
+ wakeUp();
+ } else {
+ LogUtil.d(TAG, "wakeup wakeUpInitialRet failed, not startWakeUp ");
+ }
+ }
+
+ @Override
+ public void stopWakeUp() {
+ if (wakeUpDecodeThread != null) {
+ wakeUpDecodeThread.stopWakeUp();
+ }
+ handler.removeCallbacksAndMessages(null);
+ }
+
+ @Override
+ public void releaseWakeUp() {
+ // 3.释放资源
+ int ret = wakeUpNative.wakeUpFree();
+ LogUtil.d(TAG, "wakeUpFree-ret:" + ret);
+ }
+
+ @Override
+ public void addWakeUpListener(IWakeUpListener listener) {
+ wakeUpListeners.add(listener);
+ }
+
+ /**
+ * 开始音频解码进行唤醒操作
+ */
+ private void wakeUp() {
+ wakeUpDecodeThread = new WakeUpDecodeThread(linkedBlockingDeque, wakeUpNative, handler);
+ wakeUpDecodeThread.setWakeUpListener(new WakeUpDecodeThread.IWakeUpListener() {
+ @Override
+ public void onWakeUpSucceed() {
+ // 唤醒成功
+ fireOnWakeUpSucceed();
+ }
+ });
+ wakeUpDecodeThread.startWakeUp();
+ }
+
+ private void fireOnWakeUpSucceed() {
+ for (IWakeUpListener listener : wakeUpListeners) {
+ listener.onWakeUpSucceed();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/wakeup/WakeUpNative.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,79 @@
+/*
+ * *
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.wakeup;
+
+/**
+ * 唤醒服务-native-声明
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/21.
+ */
+public class WakeUpNative {
+
+ // 加载动态库.so文件
+ static {
+ System.loadLibrary("wakeup");
+ // 唤醒词解码so库
+ System.loadLibrary("bdEASRAndroid");
+ }
+
+ /**
+ * 初始化唤醒词成功
+ *
+ * @param wakeUpWd 唤醒词,例如“小度小度”
+ * @param sFile 附件中的资源文件, 唤醒词模型数据的文件绝对路径
+ * @param mode 缺省0即可
+ * @return 返回0表示初始化唤醒词成功
+ */
+ public native int wakeUpInitial(String wakeUpWd, String sFile, int mode);
+
+ /**
+ * 重制唤醒词
+ *
+ * @return 返回0表示成功
+ */
+ public native int wakeUpReset();
+
+ /**
+ * 唤醒解码
+ *
+ * @param data 音频数据
+ * @param dataLen 数据长度
+ * @param senArr 返回结果,如果唤醒词是小度小度”,唤醒成功后会赋值
+ * @param expectNum 传1
+ * @param wakeWord_frame_len 唤醒成功返回唤醒词长度
+ * @param is_confidence true表示置信,false表示疑似唤醒
+ * @param voice_offset 唤醒词位置,需要用户传入,同时内部处理后传出
+ * @param bEd 是否为最后一帧数据
+ * @return 返回1表示唤醒,其他表示未唤醒
+ */
+ public native int wakeUpDecode(short[] data,
+ int dataLen,
+ String senArr,
+ int expectNum,
+ int wakeWord_frame_len,
+ boolean is_confidence,
+ int voice_offset,
+ boolean bEd
+ );
+
+ /**
+ * 释放资源
+ *
+ * @return 返回0表示成功
+ */
+ public native int wakeUpFree();
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/androidsystemimpl/webview/BaseWebView.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.androidsystemimpl.webview;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.net.http.SslError;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.webkit.CookieManager;
+import android.webkit.CookieSyncManager;
+import android.webkit.DownloadListener;
+import android.webkit.SslErrorHandler;
+import android.webkit.WebSettings;
+import android.webkit.WebSettings.PluginState;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+
+import com.baidu.duer.dcs.systeminterface.IWebView;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * common webView
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/19.
+ */
+@SuppressLint("SetJavaScriptEnabled")
+public class BaseWebView extends WebView implements IWebView {
+ private final List<IWebViewListener> webViewListeners =
+ Collections.synchronizedList(new ArrayList<IWebViewListener>());
+
+ public BaseWebView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ init(context);
+ }
+
+ public BaseWebView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ init(context);
+ }
+
+ public BaseWebView(Context context) {
+ super(context);
+ init(context);
+ }
+
+ @SuppressWarnings("deprecation")
+ @SuppressLint("NewApi")
+ private void init(Context context) {
+ this.setVerticalScrollBarEnabled(false);
+ this.setHorizontalScrollBarEnabled(false);
+ if (Build.VERSION.SDK_INT < 19) {
+ removeJavascriptInterface("searchBoxJavaBridge_");
+ }
+
+ WebSettings localWebSettings = this.getSettings();
+ try {
+ // 禁用file协议,http://www.tuicool.com/articles/Q36ZfuF, 防止Android WebView File域攻击
+ localWebSettings.setAllowFileAccess(false);
+ localWebSettings.setSupportZoom(false);
+ localWebSettings.setBuiltInZoomControls(false);
+ localWebSettings.setUseWideViewPort(true);
+ localWebSettings.setDomStorageEnabled(true);
+ localWebSettings.setLoadWithOverviewMode(true);
+ localWebSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);
+ localWebSettings.setPluginState(PluginState.ON);
+ // 启用数据库
+ localWebSettings.setDatabaseEnabled(true);
+ // 设置定位的数据库路径
+ String dir = context.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath();
+ localWebSettings.setGeolocationDatabasePath(dir);
+ localWebSettings.setGeolocationEnabled(true);
+ localWebSettings.setJavaScriptEnabled(true);
+ localWebSettings.setSavePassword(false);
+ String agent = localWebSettings.getUserAgentString();
+
+ localWebSettings.setUserAgentString(agent);
+ // setCookie(context, ".baidu.com", bdussCookie);
+
+ } catch (Exception e1) {
+ e1.printStackTrace();
+ }
+ this.setWebViewClient(new BridgeWebViewClient());
+ }
+
+ private void setCookie(Context context, String domain, String sessionCookie) {
+ CookieSyncManager.createInstance(context);
+ CookieManager cookieManager = CookieManager.getInstance();
+ cookieManager.setAcceptCookie(true);
+ if (sessionCookie != null) {
+ // delete old cookies
+ cookieManager.removeSessionCookie();
+ }
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ cookieManager.setCookie(domain, sessionCookie);
+
+ CookieSyncManager.createInstance(context);
+ CookieSyncManager.getInstance().sync();
+ }
+
+ public void setDownloadListener(DownloadListener listener) {
+ super.setDownloadListener(listener);
+ }
+
+ private WebViewClientListener webViewClientListen;
+
+ public void setWebViewClientListen(WebViewClientListener webViewClientListen) {
+ this.webViewClientListen = webViewClientListen;
+ }
+
+ /**
+ * 枚举网络加载返回状态 STATUS_FALSE:false
+ * STATUS_TRUE:true
+ * STATUS_UNKNOW:不知道
+ * NET_UNKNOWN:未知网络
+ */
+ public enum LoadingWebStatus {
+ STATUS_FALSE, STATUS_TRUE, STATUS_UNKNOW
+ }
+
+ @Override
+ public void linkClicked(String url) {
+ fireLinkClicked(url);
+ }
+
+ @Override
+ public void addWebViewListener(IWebViewListener listener) {
+ this.webViewListeners.add(listener);
+ }
+
+ void fireLinkClicked(String url) {
+ for (IWebViewListener listener : webViewListeners) {
+ listener.onLinkClicked(url);
+ }
+ }
+
+ public interface WebViewClientListener {
+ LoadingWebStatus shouldOverrideUrlLoading(WebView view, String url);
+
+ void onPageStarted(WebView view, String url, Bitmap favicon);
+
+ void onPageFinished(WebView view, String url);
+
+ void onReceivedError(WebView view, int errorCode, String description, String failingUrl);
+ }
+
+ public class BridgeWebViewClient extends WebViewClient {
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ LoadingWebStatus loadWebStatus = LoadingWebStatus.STATUS_UNKNOW;
+ String mUrl = url;
+ try {
+ mUrl = URLDecoder.decode(url, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ }
+ if (null != webViewClientListen) {
+ loadWebStatus = webViewClientListen.shouldOverrideUrlLoading(view, url);
+ }
+ if (LoadingWebStatus.STATUS_FALSE == loadWebStatus) {
+ return false;
+ } else if (LoadingWebStatus.STATUS_TRUE == loadWebStatus) {
+ return true;
+ } else {
+ return super.shouldOverrideUrlLoading(view, url);
+ }
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ super.onPageStarted(view, url, favicon);
+ if (null != webViewClientListen) {
+ webViewClientListen.onPageStarted(view, url, favicon);
+ }
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
+ if (null != webViewClientListen) {
+ webViewClientListen.onPageFinished(view, url);
+ }
+ }
+
+ @Override
+ public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
+ super.onReceivedError(view, errorCode, description, failingUrl);
+ if (null != webViewClientListen) {
+ webViewClientListen.onReceivedError(view, errorCode, description, failingUrl);
+ }
+ }
+
+ @Override
+ public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
+ // 当发生证书认证错误时,采用默认的处理方法handler.cancel(),停止加载问题页面
+ handler.cancel();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/alerts/AlertHandler.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.alerts;
+
+/**
+ * 定义Alerts模块的基础能力接口:开启与停止闹钟
+ * <p>
+ * Created by zhoujianliang01@baidu.com on 2017/6/5.
+ */
+public interface AlertHandler {
+ void startAlert(String alertToken);
+
+ void stopAlert(String alertToken);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/alerts/AlertScheduler.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.alerts;
+
+import com.baidu.duer.dcs.devicemodule.alerts.message.Alert;
+import com.baidu.duer.dcs.util.DateFormatterUtil;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+/**
+ * 单个的闹铃/提醒计时器
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/5.
+ */
+public class AlertScheduler extends Timer {
+ private static final String TAG = "AlertScheduler";
+ private final Alert alert;
+ private final AlertHandler handler;
+ private boolean active = false;
+
+ public AlertScheduler(final Alert alert, final AlertHandler handler) {
+ super();
+ String scheduledTimeStr = alert.getScheduledTime();
+ if (scheduledTimeStr != null && scheduledTimeStr.length() > 0) {
+ try {
+ Date date = DateFormatterUtil.toDate(alert.getScheduledTime());
+ long scheduledTime = date.getTime();
+ long delay = scheduledTime - System.currentTimeMillis();
+ LogUtil.d(TAG, "alert-delay start:" + delay);
+ if (delay > 0) {
+ this.schedule(new TimerTask() {
+ @Override
+ public void run() {
+ // 时间到了,开始闹铃
+ setActive(true);
+ handler.startAlert(alert.getToken());
+ }
+ }, delay);
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ }
+ this.alert = alert;
+ this.handler = handler;
+ }
+
+ public synchronized boolean isActive() {
+ return active;
+ }
+
+ public synchronized void setActive(boolean active) {
+ this.active = active;
+ }
+
+ @Override
+ public void cancel() {
+ super.cancel();
+ if (isActive()) {
+ handler.stopAlert(alert.getToken());
+ setActive(false);
+ }
+ }
+
+ public Alert getAlert() {
+ return alert;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/alerts/AlertsDeviceModule.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,480 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.alerts;
+
+import com.baidu.duer.dcs.devicemodule.alerts.message.Alert;
+import com.baidu.duer.dcs.devicemodule.alerts.message.AlertPayload;
+import com.baidu.duer.dcs.devicemodule.alerts.message.AlertsStatePayload;
+import com.baidu.duer.dcs.devicemodule.alerts.message.DeleteAlertPayload;
+import com.baidu.duer.dcs.devicemodule.alerts.message.SetAlertPayload;
+import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException;
+import com.baidu.duer.dcs.framework.BaseDeviceModule;
+import com.baidu.duer.dcs.framework.IMessageSender;
+import com.baidu.duer.dcs.framework.message.ClientContext;
+import com.baidu.duer.dcs.framework.message.Directive;
+import com.baidu.duer.dcs.framework.message.Event;
+import com.baidu.duer.dcs.framework.message.Header;
+import com.baidu.duer.dcs.framework.message.MessageIdHeader;
+import com.baidu.duer.dcs.framework.message.Payload;
+import com.baidu.duer.dcs.systeminterface.IAlertsDataStore;
+import com.baidu.duer.dcs.systeminterface.IHandler;
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+import com.baidu.duer.dcs.util.CommonUtil;
+import com.baidu.duer.dcs.util.DateFormatterUtil;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * Alerts模块的核心处理逻辑,如执行SetAlert、DeleteAlert指令,上传SetAlertSucceeded、DeleteAlertSucceeded等事件,
+ * 以及维护自身的端状态
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/31.
+ */
+public class AlertsDeviceModule extends BaseDeviceModule implements AlertHandler {
+ private static final String TAG = AlertsDeviceModule.class.getSimpleName();
+ // 闹铃开始是播放的音频文件
+ private static final String ALARM_NAME = "assets://alarm.mp3";
+ // 已经离alert时间点超过30分钟了
+ private static final int MINUTES_AFTER_PAST_ALERT_EXPIRES = 30;
+ // 当前的闹钟/提醒
+ private final Map<String, AlertScheduler> schedulers;
+ // 当前处于播放的
+ private final Set<String> activeAlerts;
+ private final IAlertsDataStore dataStore;
+ // 播放闹铃/提醒的mediaPlayer
+ private IMediaPlayer mediaPlayer;
+ private IHandler handler;
+ private List<IAlertListener> alertListeners;
+
+ // 提醒的状态
+ private enum AlertState {
+ PLAYING,
+ INTERRUPTED,
+ FINISHED
+ }
+
+ private AlertState alertState = AlertState.FINISHED;
+
+ public AlertsDeviceModule(IMediaPlayer mediaPlayer, IAlertsDataStore dataStore,
+ IMessageSender messageSender, IHandler handler) {
+ super(ApiConstants.NAMESPACE, messageSender);
+ this.schedulers = new ConcurrentHashMap<>();
+ this.activeAlerts = new HashSet<>();
+ this.mediaPlayer = mediaPlayer;
+ this.dataStore = dataStore;
+ this.handler = handler;
+ this.mediaPlayer.addMediaPlayerListener(mediaPlayerListener);
+ this.alertListeners = Collections.synchronizedList(new ArrayList<IAlertListener>());
+ // 先读取历史保存到文件中的提醒
+ this.loadFromDisk();
+ }
+
+ @Override
+ public ClientContext clientContext() {
+ String namespace = ApiConstants.NAMESPACE;
+ String name = ApiConstants.Events.AlertsState.NAME;
+ Header header = new Header(namespace, name);
+ Payload payload = getState();
+ return new ClientContext(header, payload);
+ }
+
+ @Override
+ public void handleDirective(Directive directive) throws HandleDirectiveException {
+ String directiveName = directive.getName();
+ if (directiveName.equals(ApiConstants.Directives.SetAlert.NAME)) {
+ // 设置一个闹铃/提醒的指令处理逻辑
+ LogUtil.d(TAG, "alert-SetAlertPayload");
+ SetAlertPayload payload = (SetAlertPayload) directive.payload;
+
+ String alertToken = payload.getToken();
+ String scheduledTime = payload.getScheduledTime();
+ LogUtil.d(TAG, "alert-scheduledTime:" + scheduledTime);
+
+ // scheduledTime 时间为ISO8601格式转换为Date
+ try {
+ Date date = DateFormatterUtil.toDate(scheduledTime);
+ LogUtil.d(TAG, "alert-ms:" + date.getTime());
+ LogUtil.d(TAG, "alert-format:" + CommonUtil.formatToDataTime(date.getTime()));
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+
+ SetAlertPayload.AlertType type = payload.getType();
+ // 如果存在一样的闹铃/提醒 就cancel掉
+ if (hasAlert(alertToken)) {
+ AlertScheduler scheduler = getScheduler(alertToken);
+ if (scheduler.getAlert().getScheduledTime().equals(scheduledTime)) {
+ return;
+ } else {
+ scheduler.cancel();
+ }
+ }
+ // 设置一个闹铃/提醒
+ Alert alert = new Alert(alertToken, type, scheduledTime);
+ add(alert, false);
+ } else if (ApiConstants.Directives.DeleteAlert.NAME.equals(directiveName)) {
+ // 删除一个闹铃/提醒的指令处理
+ LogUtil.d(TAG, "alert-DeleteAlertPayload");
+ DeleteAlertPayload payload = (DeleteAlertPayload) directive.getPayload();
+ delete(payload.getToken());
+ } else {
+ String message = "Alert cannot handle the directive";
+ throw (new HandleDirectiveException(
+ HandleDirectiveException.ExceptionType.UNSUPPORTED_OPERATION, message));
+ }
+ }
+
+ @Override
+ public void startAlert(final String alertToken) {
+ LogUtil.d(TAG, "alert-startAlert");
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ activeAlerts.add(alertToken);
+ sendAlertsRequest(ApiConstants.Events.AlertStarted.NAME, alertToken);
+ fireOnAlertStarted(alertToken);
+ if (!isAlarming()) {
+ alertState = AlertState.PLAYING;
+ if (mediaPlayer != null) {
+ mediaPlayer.play(new IMediaPlayer.MediaResource(ALARM_NAME));
+ }
+ }
+ }
+ });
+ }
+
+ @Override
+ public void stopAlert(final String alertToken) {
+ LogUtil.d(TAG, "alert-stopAlert");
+ handler.post(new Runnable() {
+ @Override
+ public void run() {
+ activeAlerts.remove(alertToken);
+ schedulers.remove(alertToken);
+ alertStopped(alertToken);
+ if (!hasActiveAlerts()) {
+ alertState = AlertState.FINISHED;
+ if (mediaPlayer != null) {
+ mediaPlayer.pause();
+ }
+ }
+ }
+ });
+ }
+
+ private void sendAlertEnteredBackgroundEvent(String alertToken) {
+ sendAlertsRequest(ApiConstants.Events.AlertEnteredBackground.NAME, alertToken);
+ }
+
+ private void sendAlertEnteredBackgroundEvent() {
+ if (hasActiveAlerts()) {
+ for (String alertToken : getActiveAlerts()) {
+ sendAlertsRequest(ApiConstants.Events.AlertEnteredBackground.NAME, alertToken);
+ }
+ }
+ }
+
+ private void sendAlertEnteredForegroundEvent(String alertToken) {
+ sendAlertsRequest(ApiConstants.Events.AlertEnteredForeground.NAME, alertToken);
+ }
+
+ public void sendAlertEnteredForegroundEvent() {
+ if (hasActiveAlerts()) {
+ for (String alertToken : getActiveAlerts()) {
+ sendAlertsRequest(ApiConstants.Events.AlertEnteredForeground.NAME, alertToken);
+ }
+ }
+ }
+
+ public void sendAlertStartedEvent(boolean isSpeaking, String alertToken) {
+ if (isSpeaking) {
+ sendAlertEnteredBackgroundEvent(alertToken);
+ } else {
+ sendAlertEnteredForegroundEvent(alertToken);
+ }
+ }
+
+ private void sendAlertsRequest(String eventName, String alertToken) {
+ Header header = new MessageIdHeader(ApiConstants.NAMESPACE, eventName);
+ Payload payload = new AlertPayload(alertToken);
+ Event event = new Event(header, payload);
+ messageSender.sendEvent(event);
+ }
+
+ /**
+ * 设置提醒/闹钟成功或者失败的上报
+ *
+ * @param alertToken alertToken
+ * @param success success
+ */
+ private void setAlert(String alertToken, boolean success) {
+ String eventName = success ? ApiConstants.Events.SetAlertSucceeded.NAME :
+ ApiConstants.Events.SetAlertFailed.NAME;
+ sendAlertsRequest(eventName, alertToken);
+ }
+
+ /**
+ * 删除提醒/闹钟成功或者失败的上报
+ *
+ * @param alertToken alertToken
+ * @param success success
+ */
+ private void deleteAlert(String alertToken, boolean success) {
+ String eventName = success ? ApiConstants.Events.DeleteAlertSucceeded.NAME :
+ ApiConstants.Events.DeleteAlertFailed.NAME;
+ sendAlertsRequest(eventName, alertToken);
+ }
+
+ /**
+ * 到了定点时间,触发了提醒/闹钟 时上报
+ *
+ * @param alertToken alertToken
+ */
+ private void fireOnAlertStarted(String alertToken) {
+ for (IAlertListener listener : alertListeners) {
+ listener.onAlertStarted(alertToken);
+ }
+ }
+
+ /**
+ * 上报AlertStopped事件
+ *
+ * @param alertToken alertToken 闹钟/提醒 唯一的标识
+ */
+ private void alertStopped(String alertToken) {
+ sendAlertsRequest(ApiConstants.Events.AlertStopped.NAME, alertToken);
+ }
+
+ /**
+ * 从文件里读取之前设置的闹铃/提醒
+ */
+ private void loadFromDisk() {
+ dataStore.readFromDisk(new IAlertsDataStore.ReadResultListener() {
+
+ @Override
+ public void onSucceed(List<Alert> alerts) {
+ if (alerts == null || alerts.size() <= 0) {
+ return;
+ }
+ List<Alert> droppedAlerts = new LinkedList<>();
+ for (final Alert alert : alerts) {
+ String scheduledTime = alert.getScheduledTime();
+ if (scheduledTime != null && scheduledTime.length() > 0) {
+ try {
+ Date date = DateFormatterUtil.toDate(alert.getScheduledTime());
+ long scheduledTimeLong = date.getTime();
+ // 已经离alert时间点超过30分钟了
+ long cur = System.currentTimeMillis();
+ if (scheduledTimeLong + MINUTES_AFTER_PAST_ALERT_EXPIRES * 60 * 1000 < cur) {
+ droppedAlerts.add(alert);
+ } else {
+ add(alert, true);
+ }
+ } catch (ParseException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ for (Alert alert : droppedAlerts) {
+ drop(alert);
+ }
+ }
+
+ @Override
+ public void onFailed(String errMsg) {
+
+ }
+ });
+ }
+
+ public boolean isAlarming() {
+ return alertState == AlertState.PLAYING;
+ }
+
+ private synchronized boolean hasAlert(String alertToken) {
+ return schedulers.containsKey(alertToken);
+ }
+
+ public synchronized boolean hasActiveAlerts() {
+ return activeAlerts != null && activeAlerts.size() > 0;
+ }
+
+ private synchronized Set<String> getActiveAlerts() {
+ return activeAlerts;
+ }
+
+ private synchronized AlertScheduler getScheduler(String alertToken) {
+ return schedulers.get(alertToken);
+ }
+
+ /**
+ * 设置一个闹钟/提醒
+ *
+ * @param alert alert
+ * @param suppressEvent suppressEvent 是否需要上报事件
+ */
+ private synchronized void add(final Alert alert, final boolean suppressEvent) {
+ LogUtil.d(TAG, "add alertToken: " + alert.getToken());
+ final AlertScheduler scheduler = new AlertScheduler(alert, this);
+ schedulers.put(alert.getToken(), scheduler);
+ dataStore.writeToDisk(getAllAlerts(), new IAlertsDataStore.WriteResultListener() {
+
+ @Override
+ public void onSucceed() {
+ if (!suppressEvent) {
+ setAlert(alert.getToken(), true);
+ }
+ }
+
+ @Override
+ public void onFailed(String errMsg) {
+ if (!suppressEvent) {
+ setAlert(alert.getToken(), false);
+ }
+ schedulers.remove(alert.getToken());
+ scheduler.cancel();
+ }
+ });
+ }
+
+ /**
+ * 删除一个闹钟
+ *
+ * @param alertToken alertToken
+ */
+ private synchronized void delete(final String alertToken) {
+ LogUtil.d(TAG, "delete alertToken: " + alertToken);
+ final AlertScheduler scheduler = schedulers.remove(alertToken);
+ if (scheduler != null) {
+ final Alert alert = scheduler.getAlert();
+ dataStore.writeToDisk(getAllAlerts(), new IAlertsDataStore.WriteResultListener() {
+ @Override
+ public void onSucceed() {
+ LogUtil.d(TAG, "delete onSucceed");
+ scheduler.cancel();
+ deleteAlert(alert.getToken(), true);
+ }
+
+ @Override
+ public void onFailed(String errMsg) {
+ LogUtil.d(TAG, "delete onFailed");
+ deleteAlert(alert.getToken(), false);
+ }
+ });
+ } else {
+ // 本地没有查询到就上报删除失败的事件
+ LogUtil.d(TAG, "delete scheduler is null");
+ deleteAlert(alertToken, false);
+ }
+ }
+
+ private synchronized List<Alert> getAllAlerts() {
+ List<Alert> list = new ArrayList<>(schedulers.size());
+ for (AlertScheduler scheduler : schedulers.values()) {
+ list.add(scheduler.getAlert());
+ }
+ return list;
+ }
+
+ /**
+ * 如果有正在播放的闹铃/提醒,就停止播放并删除该闹铃/提醒
+ */
+ public synchronized void stopActiveAlert() {
+ for (String alertToken : activeAlerts) {
+ stopAlert(alertToken);
+ return;
+ }
+ }
+
+ private void drop(final Alert alert) {
+ alertStopped(alert.getToken());
+ }
+
+ private synchronized AlertsStatePayload getState() {
+ List<Alert> all = new ArrayList<>(schedulers.size());
+ List<Alert> active = new ArrayList<>(activeAlerts.size());
+ for (AlertScheduler scheduler : schedulers.values()) {
+ Alert alert = scheduler.getAlert();
+ all.add(alert);
+
+ if (activeAlerts.contains(alert.getToken())) {
+ active.add(alert);
+ }
+ }
+ return new AlertsStatePayload(all, active);
+ }
+
+ @Override
+ public void release() {
+ if (mediaPlayer != null) {
+ mediaPlayer.release();
+ mediaPlayer.removeMediaPlayerListener(mediaPlayerListener);
+ mediaPlayer = null;
+ }
+ for (AlertScheduler scheduler : schedulers.values()) {
+ scheduler.cancel();
+ }
+ alertListeners.clear();
+ }
+
+ private IMediaPlayer.IMediaPlayerListener mediaPlayerListener = new IMediaPlayer.SimpleMediaPlayerListener() {
+ @Override
+ public void onPrepared() {
+ super.onPrepared();
+ mediaPlayer.setActive(true);
+ }
+
+ @Override
+ public void onCompletion() {
+ alertState = AlertState.FINISHED;
+ mediaPlayer.setActive(false);
+ }
+
+ @Override
+ public void onError(String error, IMediaPlayer.ErrorType errorType) {
+ super.onError(error, errorType);
+ alertState = AlertState.FINISHED;
+ mediaPlayer.setActive(false);
+ }
+ };
+
+
+ /**
+ * 闹铃/提醒回调
+ */
+ public interface IAlertListener {
+ /**
+ * 到了定点时间,触发了提醒/闹钟 时上报
+ *
+ * @param alertToken alertToken
+ */
+ void onAlertStarted(String alertToken);
+ }
+
+ public void addAlertListener(IAlertListener listener) {
+ this.alertListeners.add(listener);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/alerts/ApiConstants.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.alerts;
+
+/**
+ * 定义了表示Alerts模块的namespace、name,以及其事件、指令的name
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class ApiConstants {
+ public static final String NAMESPACE = "ai.dueros.device_interface.alerts";
+ public static final String NAME = "AlertsInterface";
+
+ public static final class Events {
+ public static final class SetAlertSucceeded {
+ public static final String NAME = SetAlertSucceeded.class.getSimpleName();
+ }
+
+ public static final class SetAlertFailed {
+ public static final String NAME = SetAlertFailed.class.getSimpleName();
+ }
+
+ public static final class DeleteAlertSucceeded {
+ public static final String NAME = DeleteAlertSucceeded.class.getSimpleName();
+ }
+
+ public static final class DeleteAlertFailed {
+ public static final String NAME = DeleteAlertFailed.class.getSimpleName();
+ }
+
+ public static final class AlertStarted {
+ public static final String NAME = AlertStarted.class.getSimpleName();
+ }
+
+ public static final class AlertStopped {
+ public static final String NAME = AlertStopped.class.getSimpleName();
+ }
+
+ public static final class AlertsState {
+ public static final String NAME = AlertsState.class.getSimpleName();
+ }
+
+ public static final class AlertEnteredForeground {
+ public static final String NAME = AlertEnteredForeground.class.getSimpleName();
+ }
+
+ public static final class AlertEnteredBackground {
+ public static final String NAME = AlertEnteredBackground.class.getSimpleName();
+ }
+ }
+
+ public static final class Directives {
+ public static final class SetAlert {
+ public static final String NAME = SetAlert.class.getSimpleName();
+ }
+
+ public static final class DeleteAlert {
+ public static final String NAME = DeleteAlert.class.getSimpleName();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/alerts/message/Alert.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.alerts.message;
+
+import org.codehaus.jackson.annotate.JsonCreator;
+import org.codehaus.jackson.annotate.JsonProperty;
+
+/**
+ * Alert 数据对象(model)
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/18.
+ */
+public class Alert {
+ private final String token;
+ private final SetAlertPayload.AlertType type;
+ // 触发时间,ISO 8601格式
+ private final String scheduledTime;
+
+ @JsonCreator
+ public Alert(@JsonProperty("token") String token, @JsonProperty("type") SetAlertPayload.AlertType type,
+ @JsonProperty("scheduledTime") String scheduledTime) {
+ this.token = token;
+ this.type = type;
+ this.scheduledTime = scheduledTime;
+ }
+
+ public String getToken() {
+ return this.token;
+ }
+
+ public SetAlertPayload.AlertType getType() {
+ return this.type;
+ }
+
+ public String getScheduledTime() {
+ return scheduledTime;
+ }
+
+ @Override
+ public int hashCode() {
+ return ((token == null) ? 0 : token.hashCode());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ Alert other = (Alert) obj;
+ if (token == null) {
+ if (other.token != null) {
+ return false;
+ }
+ } else if (!token.equals(other.token)) {
+ return false;
+ }
+ return true;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/alerts/message/AlertPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.alerts.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * Alerts模块上报各种事件的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/16.
+ */
+public class AlertPayload extends Payload {
+ // 本闹钟的唯一token
+ public String token;
+
+ public AlertPayload(String token) {
+ this.token = token;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/alerts/message/AlertsStatePayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.alerts.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+import java.util.List;
+
+/**
+ * Alerts模块端状态对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/18.
+ */
+public class AlertsStatePayload extends Payload {
+ public List<Alert> allAlerts;
+ public List<Alert> activeAlerts;
+
+ public AlertsStatePayload(List<Alert> all, List<Alert> active) {
+ this.allAlerts = all;
+ this.activeAlerts = active;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/alerts/message/DeleteAlertPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.alerts.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+import java.io.Serializable;
+
+/**
+ * DeleteAlert指令对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/17.
+ */
+public class DeleteAlertPayload extends Payload implements Serializable {
+ public String token;
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public String getToken() {
+ return token;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/alerts/message/SetAlertPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.alerts.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+import org.codehaus.jackson.annotate.JsonProperty;
+
+import java.io.Serializable;
+
+/**
+ * SetAlert指令对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/17.
+ */
+public class SetAlertPayload extends Payload implements Serializable {
+ public enum AlertType {
+ ALARM,
+ TIMER
+ }
+
+ // alert唯一token
+ private String token;
+ private AlertType type;
+ // 格式:2017-05-17T03:00:00+0000
+ private String scheduledTime;
+ private String content;
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public void setType(String type) {
+ this.type = AlertType.valueOf(type.toUpperCase());
+ }
+
+ public AlertType getType() {
+ return type;
+ }
+
+ @JsonProperty("scheduledTime")
+ public void setScheduledTime(String dateTime) {
+ scheduledTime = dateTime;
+ }
+
+ public String getScheduledTime() {
+ return scheduledTime;
+ }
+
+ public String getContent() {
+ return content;
+ }
+
+ public void setContent(String content) {
+ this.content = content;
+ }
+
+ @Override
+ public String toString() {
+ return "SetAlertPayload{"
+ + "token='"
+ + token
+ + '\''
+ + ", type="
+ + type
+ + ", scheduledTime='"
+ + scheduledTime
+ + '\''
+ + '}';
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/ApiConstants.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer;
+
+/**
+ * 定义了表示Audio Player模块的namespace、name,以及其事件、指令的name
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/1.
+ */
+public class ApiConstants {
+ public static final String NAMESPACE = "ai.dueros.device_interface.audio_player";
+ public static final String NAME = "AudioPlayerInterface";
+
+ public static final class Events {
+ public static final class PlaybackStarted {
+ public static final String NAME = PlaybackStarted.class.getSimpleName();
+ }
+
+ public static final class PlaybackNearlyFinished {
+ public static final String NAME = PlaybackNearlyFinished.class.getSimpleName();
+ }
+
+ public static final class PlaybackStutterStarted {
+ public static final String NAME = PlaybackStutterStarted.class.getSimpleName();
+ }
+
+ public static final class PlaybackStutterFinished {
+ public static final String NAME = PlaybackStutterFinished.class.getSimpleName();
+ }
+
+ public static final class PlaybackFinished {
+ public static final String NAME = PlaybackFinished.class.getSimpleName();
+ }
+
+ public static final class PlaybackFailed {
+ public static final String NAME = PlaybackFailed.class.getSimpleName();
+ }
+
+ public static final class PlaybackStopped {
+ public static final String NAME = PlaybackStopped.class.getSimpleName();
+ }
+
+ public static final class PlaybackPaused {
+ public static final String NAME = PlaybackPaused.class.getSimpleName();
+ }
+
+ public static final class PlaybackResumed {
+ public static final String NAME = PlaybackResumed.class.getSimpleName();
+ }
+
+ public static final class PlaybackQueueCleared {
+ public static final String NAME = PlaybackQueueCleared.class.getSimpleName();
+ }
+
+ public static final class ProgressReportDelayElapsed {
+ public static final String NAME = ProgressReportDelayElapsed.class.getSimpleName();
+ }
+
+ public static final class ProgressReportIntervalElapsed {
+ public static final String NAME = ProgressReportIntervalElapsed.class
+ .getSimpleName();
+ }
+
+ public static final class PlaybackState {
+ public static final String NAME = PlaybackState.class.getSimpleName();
+ }
+ }
+
+ public static final class Directives {
+ public static final class Play {
+ public static final String NAME = Play.class.getSimpleName();
+ }
+
+ public static final class Stop {
+ public static final String NAME = Stop.class.getSimpleName();
+ }
+
+ public static final class ClearQueue {
+ public static final String NAME = ClearQueue.class.getSimpleName();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/AudioPlayerDeviceModule.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,516 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer;
+
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.ClearQueuePayload;
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.PlayPayload;
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.PlaybackStatePayload;
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.StopPayload;
+import com.baidu.duer.dcs.devicemodule.audioplayer.report.AudioPlayStateReport;
+import com.baidu.duer.dcs.devicemodule.audioplayer.report.AudioPlayerProgressReporter;
+import com.baidu.duer.dcs.devicemodule.audioplayer.report.AudioPlayerTimer;
+import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException;
+import com.baidu.duer.dcs.framework.BaseDeviceModule;
+import com.baidu.duer.dcs.framework.IMessageSender;
+import com.baidu.duer.dcs.framework.message.ClientContext;
+import com.baidu.duer.dcs.framework.message.Directive;
+import com.baidu.duer.dcs.framework.message.Header;
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * 音乐播放的端能力实现,处理指令:Play,Stop,ClearQueue
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/31.
+ */
+public class AudioPlayerDeviceModule extends BaseDeviceModule {
+ private static final String TAG = AudioPlayerDeviceModule.class.getSimpleName();
+ // 播放列表,先进先出
+ private LinkedList<PlayPayload.Stream> playQueue = new LinkedList<>();
+ // 当前stream的token
+ private String latestStreamToken = "";
+ // 当前manager的播放器
+ private IMediaPlayer mediaPlayer;
+ // 播放上报
+ private AudioPlayStateReport audioPlayStateReport;
+ // 开始时的缓冲时间
+ private long bufferingStartMilliseconds;
+ // 结束时的缓冲时间
+ private long bufferingEndMilliseconds;
+ // 用来统计状态的时间间隔offsetInMilliseconds
+ private AudioPlayerTimer timer;
+ // 播放状态的上报eg:暂停,完成等
+ private AudioPlayerProgressReporter progressReporter;
+ // 回调接口
+ private List<IMediaPlayer.IMediaPlayerListener> audioPlayerListeners;
+
+ public AudioPlayerDeviceModule(IMediaPlayer mediaPlayer,
+ IMessageSender messageSender) {
+ super(ApiConstants.NAMESPACE, messageSender);
+ this.mediaPlayer = mediaPlayer;
+ this.mediaPlayer.addMediaPlayerListener(mediaPlayerListener);
+ this.audioPlayStateReport = new AudioPlayStateReport(getNameSpace(),
+ messageSender,
+ audioPlayStateReportListener);
+ this.timer = new AudioPlayerTimer();
+ this.progressReporter = new AudioPlayerProgressReporter(
+ new ProgressReportDelayEventRunnable(audioPlayStateReport),
+ new ProgressReportIntervalEventRunnable(audioPlayStateReport), timer);
+ this.audioPlayerListeners = Collections.synchronizedList(
+ new ArrayList<IMediaPlayer.IMediaPlayerListener>());
+ }
+
+ @Override
+ public ClientContext clientContext() {
+ String namespace = ApiConstants.NAMESPACE;
+ String name = ApiConstants.Events.PlaybackState.NAME;
+ Header header = new Header(namespace, name);
+ PlaybackStatePayload payload = new PlaybackStatePayload(latestStreamToken,
+ mediaPlayer.getCurrentPosition(),
+ audioPlayStateReport.getState().name());
+ return new ClientContext(header, payload);
+ }
+
+ @Override
+ public void handleDirective(Directive directive) throws HandleDirectiveException {
+ LogUtil.d(TAG, "dcs-play-directive:" + directive.rawMessage);
+ String directiveName = directive.getName();
+ LogUtil.d(TAG, "dcs-play-directiveName:" + directiveName);
+ if (ApiConstants.Directives.Play.NAME.equals(directiveName)) {
+ handlePlay((PlayPayload) directive.getPayload());
+ } else if (ApiConstants.Directives.Stop.NAME.equals(directiveName)) {
+ handleStop((StopPayload) directive.getPayload());
+ } else if (ApiConstants.Directives.ClearQueue.NAME.equals(directiveName)) {
+ handleClearQueue((ClearQueuePayload) directive.getPayload());
+ } else {
+ String message = "audioPlayer cannot handle the directive";
+ throw (new HandleDirectiveException(
+ HandleDirectiveException.ExceptionType.UNSUPPORTED_OPERATION, message));
+ }
+ }
+
+ /**
+ * 处理播放指令(Play)
+ *
+ * @param payload payload
+ */
+ private void handlePlay(PlayPayload payload) {
+ PlayPayload.AudioItem item = payload.audioItem;
+ if (payload.playBehavior == PlayPayload.PlayBehavior.REPLACE_ALL) {
+ clearAll();
+ } else if (payload.playBehavior == PlayPayload.PlayBehavior.REPLACE_ENQUEUED) {
+ clearEnqueued();
+ }
+ final PlayPayload.Stream stream = item.stream;
+ String streamUrl = stream.url;
+ String streamId = stream.token;
+ long offset = stream.offsetInMilliseconds;
+ LogUtil.i(TAG, "URL:" + streamUrl);
+ LogUtil.i(TAG, "StreamId:" + streamId);
+ LogUtil.i(TAG, "Offset:" + offset);
+ add(stream);
+ }
+
+ /**
+ * 处理停止指令(Stop)
+ *
+ * @param payload payload
+ */
+ private void handleStop(StopPayload payload) {
+ stop();
+ }
+
+ /**
+ * 处理清空队列指令(Stop)
+ *
+ * @param clearQueuePayload clearQueuePayload
+ */
+ private void handleClearQueue(ClearQueuePayload clearQueuePayload) {
+ // 清除播放列表,并停止当前播放的音频(如果有)
+ if (clearQueuePayload.clearBehavior == ClearQueuePayload.ClearBehavior.CLEAR_ALL) {
+ audioPlayStateReport.clearQueueAll();
+ clearAll();
+ } else if (clearQueuePayload.clearBehavior == ClearQueuePayload.ClearBehavior.CLEAR_ENQUEUED) {
+ // 清除播放列表,但不影响当前播放
+ audioPlayStateReport.clearQueueEnqueued();
+ clearEnqueued();
+ }
+ }
+
+ private void add(PlayPayload.Stream stream) {
+ String expectedPreviousToken = stream.expectedPreviousToken;
+ boolean startPlaying = playQueue.isEmpty();
+ if (expectedPreviousToken == null || latestStreamToken.isEmpty()
+ || latestStreamToken.equals(expectedPreviousToken)) {
+ playQueue.add(stream);
+ }
+ LogUtil.d(TAG, " coming playQueue size :" + playQueue.size());
+ if (startPlaying) {
+ startPlay();
+ }
+ }
+
+ /**
+ * 开始播放音乐
+ */
+ private void startPlay() {
+ if (playQueue.isEmpty()) {
+ LogUtil.d(TAG, "startPlay-playQueue isEmpty !!");
+ return;
+ }
+ PlayPayload.Stream currentStream = playQueue.peek();
+ if (currentStream == null) {
+ return;
+ }
+ latestStreamToken = currentStream.token;
+ String url = currentStream.url;
+ // 从哪个位置开始播放
+ long offset = currentStream.offsetInMilliseconds;
+ // 判断是否是流类型还是URL类型
+ if (currentStream.hasAttachedContent()) {
+ mediaPlayer.play(new IMediaPlayer.MediaResource(currentStream.getAttachedContent()));
+ } else {
+ mediaPlayer.play(new IMediaPlayer.MediaResource(url));
+ }
+ mediaPlayer.seekTo((int) offset);
+ }
+
+ private IMediaPlayer.IMediaPlayerListener mediaPlayerListener = new IMediaPlayer.SimpleMediaPlayerListener() {
+ // 是否处于暂停
+ private boolean isPause;
+ // 是否第一次到达了100
+ private boolean stutterFinished;
+ // 是否处于上报ProgressReport事件中
+ private boolean progressReporting;
+ // 是否处于缓冲中
+ private boolean bufferUnderRunInProgress;
+
+ @Override
+ public void onInit() {
+ super.onInit();
+ LogUtil.d(TAG, "onInit");
+ isPause = false;
+ stutterFinished = false;
+ progressReporting = false;
+ bufferUnderRunInProgress = false;
+ }
+
+ @Override
+ public void onPrepared() {
+ super.onPrepared();
+ LogUtil.d(TAG, "onPrepared");
+ fireOnPrepared();
+ }
+
+ @Override
+ public void onPlaying() {
+ super.onPlaying();
+ LogUtil.d(TAG, "onPlaying");
+ // 暂停后继续播放
+ if (isPause) {
+ isPause = false;
+ audioPlayStateReport.playbackResumed();
+ } else {
+ // 第一次播放
+ PlayPayload.Stream stream = playQueue.peek();
+ if (stream == null) {
+ return;
+ }
+ long offset = stream.offsetInMilliseconds;
+ LogUtil.d(TAG, "onPlaying---Duration----:" + mediaPlayer.getDuration());
+ timer.reset(offset, mediaPlayer.getDuration());
+
+ // 上报PlaybackStarted事件
+ audioPlayStateReport.playbackStarted();
+ }
+ startTimerAndProgressReporter();
+ fireOnPlaying();
+ }
+
+ @Override
+ public void onPaused() {
+ LogUtil.d(TAG, "onPaused");
+ stopTimerAndProgressReporter();
+ isPause = true;
+ audioPlayStateReport.playbackPaused();
+ fireOnPaused();
+ }
+
+ @Override
+ public void onStopped() {
+ super.onStopped();
+ stopTimerAndProgressReporter();
+ audioPlayStateReport.playbackStopped();
+ fireOnStopped();
+ }
+
+ @Override
+ public void onCompletion() {
+ LogUtil.d(TAG, "onCompletion");
+ stopTimerAndProgressReporter();
+ playQueue.poll();
+ audioPlayStateReport.playbackFinished();
+ audioPlayStateReport.playbackNearlyFinished();
+ if (!playQueue.isEmpty()) {
+ startPlay();
+ }
+ fireOnCompletion();
+ }
+
+ @Override
+ public void onRelease() {
+ LogUtil.d(TAG, "onError");
+ stopTimerAndProgressReporter();
+ fireOnRelease();
+ }
+
+ @Override
+ public void onError(String error, IMediaPlayer.ErrorType errorType) {
+ LogUtil.d(TAG, "onError");
+ playQueue.clear();
+ audioPlayStateReport.playbackFailed(errorType);
+ stopTimerAndProgressReporter();
+ fireOnError(error, errorType);
+ }
+
+ @Override
+ public void onBufferingUpdate(int percent) {
+ LogUtil.d(TAG, "onBufferingUpdate:" + percent);
+ fireOnBufferingUpdate(percent);
+ PlayPayload.Stream stream = playQueue.peek();
+ if (stream == null) {
+ return;
+ }
+ // Play指令有progressReportDelayInMilliseconds
+ if (!progressReporting && stream.getProgressReportRequired()) {
+ LogUtil.d(TAG, "onBufferingUpdate:" + percent);
+ progressReporting = true;
+ progressReporter.disable();
+ progressReporter.setup(stream.progressReport);
+ long offset = stream.offsetInMilliseconds;
+ timer.reset(offset, mediaPlayer.getDuration());
+ startTimerAndProgressReporter();
+ }
+
+ // 已经缓冲完成了
+ if (stutterFinished) {
+ return;
+ }
+ // 开始缓冲
+ if (!bufferUnderRunInProgress) {
+ LogUtil.d(TAG, "==playbackStutterStarted");
+ bufferUnderRunInProgress = true;
+ bufferingStartMilliseconds = System.currentTimeMillis();
+ audioPlayStateReport.playbackStutterStarted();
+ }
+ // 缓冲完毕后上报playbackStutterFinished
+ if (percent >= 100) {
+ stutterFinished = true;
+ bufferingEndMilliseconds = System.currentTimeMillis();
+ audioPlayStateReport.playbackStutterFinished();
+ }
+ }
+ };
+
+ private void startTimerAndProgressReporter() {
+ timer.start();
+ if (progressReporter.isSetup()) {
+ progressReporter.start();
+ }
+ }
+
+ private void stopTimerAndProgressReporter() {
+ timer.stop();
+ progressReporter.stop();
+ }
+
+ private void clearAll() {
+ stop();
+ playQueue.clear();
+ }
+
+ private void clearEnqueued() {
+ PlayPayload.Stream top = playQueue.poll();
+ playQueue.clear();
+ if (top != null) {
+ playQueue.add(top);
+ }
+ }
+
+ private void stop() {
+ if (!playQueue.isEmpty() && isPlayingOrPaused()) {
+ stopTimerAndProgressReporter();
+ // 要把播放策略中的对应的那一条删除了
+ mediaPlayer.stop();
+ }
+ }
+
+ private boolean isPlaying() {
+ return (audioPlayStateReport.getState() == AudioPlayStateReport.AudioPlayerState.PLAYING
+ || audioPlayStateReport.getState() == AudioPlayStateReport.AudioPlayerState.PAUSED
+ || audioPlayStateReport.getState() == AudioPlayStateReport.AudioPlayerState.BUFFER_UNDERRUN);
+ }
+
+ private boolean isPlayingOrPaused() {
+ return isPlaying() || audioPlayStateReport.getState() == AudioPlayStateReport.AudioPlayerState.PAUSED;
+ }
+
+ @Override
+ public void release() {
+ if (mediaPlayer != null) {
+ mediaPlayer.release();
+ mediaPlayer.removeMediaPlayerListener(mediaPlayerListener);
+ }
+ stopTimerAndProgressReporter();
+ audioPlayerListeners.clear();
+ }
+
+ /**
+ * 播放上报时需要的信息
+ */
+ private AudioPlayStateReport.AudioPlayStateReportListener audioPlayStateReportListener =
+ new AudioPlayStateReport.AudioPlayStateReportListener() {
+ @Override
+ public String getCurrentStreamToken() {
+ return latestStreamToken;
+ }
+
+ @Override
+ public long getCurrentOffsetInMilliseconds() {
+ return getCurrentOffsetInMillisecondsByTime();
+ }
+
+ @Override
+ public long getStutterDurationInMilliseconds() {
+ // 缓冲时间ms
+ return bufferingEndMilliseconds - bufferingStartMilliseconds;
+ }
+ };
+
+ private long getCurrentOffsetInMillisecondsByTime() {
+ AudioPlayStateReport.AudioPlayerState playerActivity = audioPlayStateReport.getState();
+ long offset;
+ switch (playerActivity) {
+ case PLAYING:
+ case PAUSED:
+ case BUFFER_UNDERRUN:
+ case STOPPED:
+ case FINISHED:
+ offset = timer.getOffsetInMilliseconds();
+ break;
+ case IDLE:
+ default:
+ offset = 0;
+ }
+ LogUtil.d(TAG, "getCurrentOffsetInMilliseconds offset:" + offset);
+ return offset;
+ }
+
+ private static class ProgressReportDelayEventRunnable implements Runnable {
+ private final AudioPlayStateReport audioPlayStateReport;
+
+ ProgressReportDelayEventRunnable(AudioPlayStateReport audioPlayStateReport) {
+ this.audioPlayStateReport = audioPlayStateReport;
+ }
+
+ @Override
+ public void run() {
+ audioPlayStateReport.reportProgressDelay();
+ }
+ }
+
+ private static class ProgressReportIntervalEventRunnable implements Runnable {
+ private final AudioPlayStateReport audioPlayStateReport;
+
+ ProgressReportIntervalEventRunnable(AudioPlayStateReport audioPlayStateReport) {
+ this.audioPlayStateReport = audioPlayStateReport;
+ }
+
+ @Override
+ public void run() {
+ audioPlayStateReport.reportProgressInterval();
+ }
+ }
+
+ private void fireOnPrepared() {
+ for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) {
+ listener.onPrepared();
+ }
+ }
+
+ private void fireOnRelease() {
+ for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) {
+ listener.onRelease();
+ }
+ }
+
+ private void fireOnPlaying() {
+ for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) {
+ listener.onPlaying();
+ }
+ }
+
+ private void fireOnPaused() {
+ for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) {
+ listener.onPaused();
+ }
+ }
+
+ private void fireOnStopped() {
+ for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) {
+ listener.onStopped();
+ }
+ }
+
+ private void fireOnCompletion() {
+ for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) {
+ listener.onCompletion();
+ }
+ }
+
+ private void fireOnError(String error, IMediaPlayer.ErrorType errorType) {
+ for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) {
+ listener.onError(error, errorType);
+ }
+ }
+
+ private void fireOnBufferingUpdate(int percent) {
+ for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) {
+ listener.onBufferingUpdate(percent);
+ }
+ }
+
+ private void fireBufferingStart() {
+ for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) {
+ listener.onBufferingStart();
+ }
+ }
+
+ private void fireBufferingEnd() {
+ for (IMediaPlayer.IMediaPlayerListener listener : audioPlayerListeners) {
+ listener.onBufferingEnd();
+ }
+ }
+
+ public void addAudioPlayListener(IMediaPlayer.IMediaPlayerListener listener) {
+ audioPlayerListeners.add(listener);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/message/AudioPlayerPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * Audio Player模块上报各种事件的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/4.
+ */
+public class AudioPlayerPayload extends Payload {
+ public String token;
+ public long offsetInMilliseconds;
+
+ public AudioPlayerPayload(String token, long offsetInMilliseconds) {
+ this.token = token;
+ this.offsetInMilliseconds = offsetInMilliseconds;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/message/ClearQueuePayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * ClearQueue指令对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/1.
+ */
+public class ClearQueuePayload extends Payload {
+ public enum ClearBehavior {
+ CLEAR_ENQUEUED,
+ CLEAR_ALL
+ }
+
+ public ClearBehavior clearBehavior;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/message/PlayPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+import java.io.InputStream;
+import java.io.Serializable;
+
+/**
+ * Audio Player模块Play指令对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/31.
+ */
+public class PlayPayload extends Payload {
+ public PlayBehavior playBehavior;
+ public AudioItem audioItem;
+
+ public enum PlayBehavior {
+ REPLACE_ALL,
+ ENQUEUE,
+ REPLACE_ENQUEUED
+ }
+
+ public static class AudioItem implements Serializable {
+ public String audioItemId;
+ public Stream stream;
+ }
+
+ public static class Stream implements Serializable {
+ public String url;
+ public String token;
+ public String expiryTime;
+ public long offsetInMilliseconds;
+ public String expectedPreviousToken;
+ public String streamFormat;
+ public boolean urlIsAContentId;
+ public ProgressReport progressReport;
+ @JsonIgnore
+ public InputStream attachedContent;
+
+ public boolean getProgressReportRequired() {
+ return progressReport != null && progressReport.isRequired();
+ }
+
+ public void setUrl(String url) {
+ urlIsAContentId = url.startsWith("cid");
+ if (urlIsAContentId) {
+ this.url = url.substring(4);
+ } else {
+ this.url = url;
+ }
+ }
+
+ public boolean requiresAttachedContent() {
+ return urlIsAContentId && !hasAttachedContent();
+ }
+
+ public boolean hasAttachedContent() {
+ return attachedContent != null;
+ }
+
+ @JsonIgnore
+ public InputStream getAttachedContent() {
+ return attachedContent;
+ }
+ }
+
+ public static class ProgressReport implements Serializable {
+ public long progressReportDelayInMilliseconds;
+ public long progressReportIntervalInMilliseconds;
+
+ public boolean isRequired() {
+ return progressReportDelayInMilliseconds > 0 || progressReportIntervalInMilliseconds > 0;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/message/PlaybackFailedPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+
+/**
+ * Audio Player模块上报PlaybackFailed事件对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/8.
+ */
+public class PlaybackFailedPayload extends Payload {
+ private String token;
+ private PlaybackStatePayload currentPlaybackState;
+ private ErrorStructure error;
+
+ public PlaybackFailedPayload(String token, PlaybackStatePayload playbackState,
+ IMediaPlayer.ErrorType errorType) {
+ this.token = token;
+ this.currentPlaybackState = playbackState;
+ error = new ErrorStructure(errorType);
+ }
+
+ public String getToken() {
+ return token;
+ }
+
+ public PlaybackStatePayload getCurrentPlaybackState() {
+ return currentPlaybackState;
+ }
+
+ public ErrorStructure getError() {
+ return error;
+ }
+
+ private static final class ErrorStructure {
+ private IMediaPlayer.ErrorType type;
+ private String message;
+
+ public ErrorStructure(IMediaPlayer.ErrorType type) {
+ this.type = type;
+ this.message = type.getMessage();
+ }
+
+ public IMediaPlayer.ErrorType getType() {
+ return type;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/message/PlaybackStatePayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * Audio Player模块端状态对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/1.
+ */
+public class PlaybackStatePayload extends Payload {
+ public String token;
+ public long offsetInMilliseconds;
+ public String playerActivity;
+
+ public PlaybackStatePayload(String token, long offsetInMilliseconds, String playerActivity) {
+ this.token = token;
+ this.offsetInMilliseconds = offsetInMilliseconds;
+ this.playerActivity = playerActivity;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/message/PlaybackStutterFinishedPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer.message;
+
+/**
+ * Audio Player模块上报PlaybackStutterFinished事件对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/4.
+ */
+public class PlaybackStutterFinishedPayload extends AudioPlayerPayload {
+ public long stutterDurationInMilliseconds;
+
+ public PlaybackStutterFinishedPayload(String token, long offsetInMilliseconds,
+ long stutterDurationInMilliseconds) {
+ super(token, offsetInMilliseconds);
+ this.stutterDurationInMilliseconds = stutterDurationInMilliseconds;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/message/StopPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * Audio Player模块Stop指令对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/6.
+ */
+public class StopPayload extends Payload {
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/report/AudioPlayStateReport.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer.report;
+
+import com.baidu.duer.dcs.devicemodule.audioplayer.ApiConstants;
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.AudioPlayerPayload;
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.PlaybackFailedPayload;
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.PlaybackStatePayload;
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.PlaybackStutterFinishedPayload;
+import com.baidu.duer.dcs.framework.IMessageSender;
+import com.baidu.duer.dcs.framework.message.Event;
+import com.baidu.duer.dcs.framework.message.Header;
+import com.baidu.duer.dcs.framework.message.MessageIdHeader;
+import com.baidu.duer.dcs.framework.message.Payload;
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+
+/**
+ * Audio Player模块各种事件上报的处理,同时维护当前的端状态
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/1.
+ */
+public class AudioPlayStateReport {
+ public enum AudioPlayerState {
+ IDLE,
+ PLAYING,
+ PAUSED,
+ FINISHED,
+ STOPPED,
+ BUFFER_UNDERRUN
+ }
+
+ private AudioPlayerState currentState = AudioPlayerState.FINISHED;
+ private IMessageSender messageSender;
+ private String namespace;
+ private AudioPlayStateReportListener audioPlayStateReportListener;
+
+ public AudioPlayStateReport(String namespace, IMessageSender messageSender,
+ AudioPlayStateReportListener audioPlayStateReportListener) {
+ this.namespace = namespace;
+ this.messageSender = messageSender;
+ this.audioPlayStateReportListener = audioPlayStateReportListener;
+
+ }
+
+ public AudioPlayerState getState() {
+ return currentState;
+ }
+
+ public void playbackResumed() {
+ currentState = AudioPlayerState.PLAYING;
+ Event event = createAudioPlayerEvent(ApiConstants.Events.PlaybackResumed.NAME,
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds());
+ messageSender.sendEvent(event);
+ }
+
+ public void playbackFinished() {
+ currentState = AudioPlayerState.FINISHED;
+ Event event = createAudioPlayerEvent(ApiConstants.Events.PlaybackFinished.NAME,
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds());
+ messageSender.sendEvent(event);
+ }
+
+ public void playbackStarted() {
+ currentState = AudioPlayerState.PLAYING;
+ Event event = createAudioPlayerEvent(ApiConstants.Events.PlaybackStarted.NAME,
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds());
+ messageSender.sendEvent(event);
+ }
+
+ public void playbackFailed(IMediaPlayer.ErrorType errorType) {
+ currentState = AudioPlayerState.STOPPED;
+ long offset = audioPlayStateReportListener.getCurrentOffsetInMilliseconds();
+ PlaybackStatePayload playbackStatePayload =
+ new PlaybackStatePayload(audioPlayStateReportListener.getCurrentStreamToken(),
+ offset, currentState.toString());
+
+ Header header = new MessageIdHeader(namespace,
+ ApiConstants.Events.PlaybackFailed.NAME);
+ Event event = new Event(header,
+ new PlaybackFailedPayload(audioPlayStateReportListener.getCurrentStreamToken(),
+ playbackStatePayload, errorType));
+
+ messageSender.sendEvent(event);
+ }
+
+ public void playbackPaused() {
+ currentState = AudioPlayerState.PAUSED;
+ Event event = createAudioPlayerEvent(ApiConstants.Events.PlaybackPaused.NAME,
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds());
+ messageSender.sendEvent(event);
+ }
+
+ public void playbackNearlyFinished() {
+ currentState = AudioPlayerState.FINISHED;
+ Event event = createAudioPlayerEvent(ApiConstants.Events.PlaybackNearlyFinished.NAME,
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds());
+ messageSender.sendEvent(event);
+ }
+
+ public void playbackStutterStarted() {
+ currentState = AudioPlayerState.BUFFER_UNDERRUN;
+ Event event = createAudioPlayerEvent(ApiConstants.Events.PlaybackStutterStarted.NAME,
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds());
+ messageSender.sendEvent(event);
+ }
+
+ public void playbackStutterFinished() {
+ currentState = AudioPlayerState.PLAYING;
+ Event event = createAudioPlayerPlaybackStutterFinishedEvent(
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds(),
+ audioPlayStateReportListener.getStutterDurationInMilliseconds()
+ );
+ messageSender.sendEvent(event);
+ }
+
+ public void playbackStopped() {
+ currentState = AudioPlayerState.STOPPED;
+ Event event = createAudioPlayerEvent(ApiConstants.Events.PlaybackStopped.NAME,
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds());
+ messageSender.sendEvent(event);
+ }
+
+ public void clearQueueAll() {
+ Event event = createAudioPlayerPlaybackQueueClearedEvent();
+ messageSender.sendEvent(event);
+ if (currentState == AudioPlayerState.PLAYING || currentState == AudioPlayerState.PAUSED
+ || currentState == AudioPlayerState.BUFFER_UNDERRUN) {
+ currentState = AudioPlayerState.STOPPED;
+ Event eventStopped = createAudioPlayerEvent(ApiConstants.Events.PlaybackStopped.NAME,
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds());
+ messageSender.sendEvent(eventStopped);
+ }
+ }
+
+ public void clearQueueEnqueued() {
+ Event event = createAudioPlayerPlaybackQueueClearedEvent();
+ messageSender.sendEvent(event);
+ }
+
+ private Event createAudioPlayerEvent(String name, String streamToken,
+ long offsetInMilliseconds) {
+ Header header = new MessageIdHeader(namespace, name);
+ Payload payload = new AudioPlayerPayload(streamToken, offsetInMilliseconds);
+ return new Event(header, payload);
+ }
+
+ private Event createAudioPlayerPlaybackQueueClearedEvent() {
+ Header header = new MessageIdHeader(ApiConstants.NAMESPACE,
+ ApiConstants.Events.PlaybackQueueCleared.NAME);
+ return new Event(header, new Payload());
+ }
+
+ private Event createAudioPlayerPlaybackStutterFinishedEvent(String streamToken,
+ long offsetInMilliseconds,
+ long stutterDurationInMilliseconds) {
+ Header header = new MessageIdHeader(ApiConstants.NAMESPACE,
+ ApiConstants.Events.PlaybackStutterFinished.NAME);
+ return new Event(header, new PlaybackStutterFinishedPayload(streamToken,
+ offsetInMilliseconds, stutterDurationInMilliseconds));
+ }
+
+ public void reportProgressDelay() {
+ currentState = AudioPlayerState.PLAYING;
+ Event event = createAudioPlayerEvent(ApiConstants.Events.ProgressReportDelayElapsed.NAME,
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds());
+ messageSender.sendEvent(event);
+ }
+
+ public void reportProgressInterval() {
+ currentState = AudioPlayerState.PLAYING;
+ Event event = createAudioPlayerEvent(ApiConstants.Events.ProgressReportIntervalElapsed.NAME,
+ audioPlayStateReportListener.getCurrentStreamToken(),
+ audioPlayStateReportListener.getCurrentOffsetInMilliseconds());
+ messageSender.sendEvent(event);
+ }
+
+ public interface AudioPlayStateReportListener {
+ String getCurrentStreamToken();
+
+ long getCurrentOffsetInMilliseconds();
+
+ long getStutterDurationInMilliseconds();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/report/AudioPlayerProgressReporter.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer.report;
+
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.PlayPayload;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 当服务器返回Play指令有progressReportDelayInMilliseconds,
+ * <p>
+ * ProgressReportDelayElapsed和ProgressReportIntervalElapsed事件的上报
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/22.
+ */
+public class AudioPlayerProgressReporter {
+ private final ScheduledExecutorService eventScheduler = Executors.newScheduledThreadPool(1);
+ private ScheduledFuture<?> progressReportDelayFuture;
+ private ScheduledFuture<?> progressReportIntervalFuture;
+ private final Runnable progressReportDelayRunnable;
+ private final Runnable progressReportIntervalRunnable;
+ private final AudioPlayerTimer audioPlayerTimer;
+ private long progressReportDelay;
+ private long progressReportInterval;
+ private boolean isSetup;
+
+ public AudioPlayerProgressReporter(Runnable progressReportDelayRunnable,
+ Runnable progressReportIntervalRunnable,
+ AudioPlayerTimer audioPlayerTimer) {
+ if (progressReportDelayRunnable == null
+ || progressReportIntervalRunnable == null
+ || audioPlayerTimer == null) {
+ throw new IllegalArgumentException("All arguments must be provided.");
+ }
+ this.progressReportDelayRunnable = progressReportDelayRunnable;
+ this.progressReportIntervalRunnable = progressReportIntervalRunnable;
+ this.audioPlayerTimer = audioPlayerTimer;
+ this.isSetup = false;
+ }
+
+ public synchronized void setup(PlayPayload.ProgressReport progressReport) {
+ if (progressReport == null) {
+ String errorMessage = "ProgressReport must not be null.";
+ throw new IllegalArgumentException(errorMessage);
+ }
+ if (isSetup) {
+ String errorMessage = "AudioPlayerProgressReporter has already been setup. "
+ + "Please disable it before setting it up again.";
+ throw new IllegalStateException(errorMessage);
+ }
+
+ cancelEvents();
+ progressReportDelay = progressReport.progressReportDelayInMilliseconds;
+ progressReportInterval = progressReport.progressReportIntervalInMilliseconds;
+ isSetup = true;
+ }
+
+ public synchronized void disable() {
+ isSetup = false;
+ cancelEvents();
+ progressReportDelay = 0;
+ progressReportInterval = 0;
+ }
+
+ public synchronized void start() {
+ cancelEvents();
+
+ if (!isSetup) {
+ String errorMessage = "AudioPlayerProgressReporter cannot be started "
+ + "because it has not been setup yet.";
+ throw new IllegalStateException(errorMessage);
+ }
+
+ long currentOffsetIntoTrack = audioPlayerTimer.getOffsetInMilliseconds();
+
+ long timeUntilDelayReport = progressReportDelay - currentOffsetIntoTrack;
+ if (timeUntilDelayReport > 0) {
+ scheduleDelayEvent(timeUntilDelayReport);
+ }
+
+ long timeUntilIntervalReport = progressReportInterval == 0 ? 0 :
+ progressReportInterval - (currentOffsetIntoTrack % progressReportInterval);
+ if (timeUntilIntervalReport > 0) {
+ scheduleIntervalEvent(timeUntilIntervalReport, progressReportInterval);
+ }
+ }
+
+ public synchronized void stop() {
+ cancelEvents();
+ }
+
+ public synchronized boolean isSetup() {
+ return isSetup;
+ }
+
+ private void scheduleDelayEvent(long delay) {
+ progressReportDelayFuture = eventScheduler.schedule(progressReportDelayRunnable, delay,
+ TimeUnit.MILLISECONDS);
+ }
+
+ private void scheduleIntervalEvent(long delay, long interval) {
+ progressReportIntervalFuture = eventScheduler.scheduleAtFixedRate(
+ progressReportIntervalRunnable, delay, interval, TimeUnit.MILLISECONDS);
+ }
+
+ private void cancelEvents() {
+ if (progressReportDelayFuture != null && !progressReportDelayFuture.isDone()) {
+ progressReportDelayFuture.cancel(false);
+ }
+ if (progressReportIntervalFuture != null && !progressReportIntervalFuture.isDone()) {
+ progressReportIntervalFuture.cancel(false);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/audioplayer/report/AudioPlayerTimer.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.audioplayer.report;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * audio 播放统计OffsetInMilliseconds
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/22.
+ */
+public class AudioPlayerTimer {
+ private long startNano;
+ private long elapsedTimeMs;
+ private long totalStreamLength;
+ private boolean isPlaying = false;
+
+ public synchronized void start() {
+ startNano = System.nanoTime();
+ isPlaying = true;
+ }
+
+ public synchronized void stop() {
+ if (isPlaying) {
+ elapsedTimeMs += getCurrentOffsetInMilliseconds();
+ isPlaying = false;
+ }
+ }
+
+ public synchronized long getOffsetInMilliseconds() {
+ long offset = elapsedTimeMs + (isPlaying ? getCurrentOffsetInMilliseconds() : 0);
+ if (totalStreamLength > 0) {
+ offset = Math.min(totalStreamLength, offset);
+ }
+ return offset;
+ }
+
+ public void reset() {
+ reset(0);
+ }
+
+ public void reset(long startPosition) {
+ reset(startPosition, -1);
+ }
+
+ public synchronized void reset(long startPosition, long maxPosition) {
+ elapsedTimeMs = startPosition;
+ isPlaying = false;
+ startNano = System.nanoTime();
+ totalStreamLength = maxPosition;
+ }
+
+ private long getCurrentOffsetInMilliseconds() {
+ return TimeUnit.MILLISECONDS.convert(System.nanoTime() - startNano, TimeUnit.NANOSECONDS);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/playbackcontroller/ApiConstants.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.playbackcontroller;
+
+/**
+ * 定义了表示PlaybackController模块的namespace、name,以及其事件、指令的name
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class ApiConstants {
+ public static final String NAMESPACE = "ai.dueros.device_interface.playback_controller";
+ public static final String NAME = "PlaybackControllerInterface";
+
+ public static final class Events {
+ public static final class NextCommandIssued {
+ public static final String NAME = NextCommandIssued.class.getSimpleName();
+ }
+
+ public static final class PreviousCommandIssued {
+ public static final String NAME = PreviousCommandIssued.class.getSimpleName();
+ }
+
+ public static final class PlayCommandIssued {
+ public static final String NAME = PlayCommandIssued.class.getSimpleName();
+ }
+
+ public static final class PauseCommandIssued {
+ public static final String NAME = PauseCommandIssued.class.getSimpleName();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/playbackcontroller/PlaybackControllerDeviceModule.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.playbackcontroller;
+
+import com.baidu.duer.dcs.devicemodule.alerts.AlertsDeviceModule;
+import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException;
+import com.baidu.duer.dcs.framework.BaseDeviceModule;
+import com.baidu.duer.dcs.framework.IMessageSender;
+import com.baidu.duer.dcs.framework.IResponseListener;
+import com.baidu.duer.dcs.framework.message.ClientContext;
+import com.baidu.duer.dcs.framework.message.Directive;
+import com.baidu.duer.dcs.framework.message.Event;
+import com.baidu.duer.dcs.framework.message.Header;
+import com.baidu.duer.dcs.framework.message.MessageIdHeader;
+import com.baidu.duer.dcs.framework.message.Payload;
+import com.baidu.duer.dcs.systeminterface.IPlaybackController;
+
+/**
+ * 音频播放控制
+ * <p>
+ * 用户按了端上的播放/暂停等控制按钮,或者通过端上的GUI进行了此类操作时,上报PlayCommandIssued、PauseCommandIssued等事件
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public class PlaybackControllerDeviceModule extends BaseDeviceModule {
+ private AlertsDeviceModule mAlertsDeviceModule;
+
+ public enum PlaybackAction {
+ PLAY,
+ PAUSE,
+ PREVIOUS,
+ NEXT
+ }
+
+ public PlaybackControllerDeviceModule(IPlaybackController playback, IMessageSender messageSender,
+ AlertsDeviceModule alertsDeviceModule) {
+ super(ApiConstants.NAMESPACE, messageSender);
+ this.mAlertsDeviceModule = alertsDeviceModule;
+ playback.registerPlaybackListener(new IPlaybackController.IPlaybackListener() {
+ @Override
+ public void onPlay(IResponseListener responseListener) {
+ handlePlaybackAction(PlaybackAction.PLAY, responseListener);
+ }
+
+ @Override
+ public void onPause(IResponseListener responseListener) {
+ handlePlaybackAction(PlaybackAction.PAUSE, responseListener);
+ }
+
+ @Override
+ public void onPrevious(IResponseListener responseListener) {
+ handlePlaybackAction(PlaybackAction.PREVIOUS, responseListener);
+ }
+
+ @Override
+ public void onNext(IResponseListener responseListener) {
+ handlePlaybackAction(PlaybackAction.NEXT, responseListener);
+ }
+ });
+ }
+
+ @Override
+ public ClientContext clientContext() {
+ return null;
+ }
+
+ @Override
+ public void handleDirective(Directive directive) throws HandleDirectiveException {
+ }
+
+ @Override
+ public void release() {
+ }
+
+ private void handlePlaybackAction(PlaybackAction action, IResponseListener responseListener) {
+ switch (action) {
+ case PLAY:
+ if (mAlertsDeviceModule.hasActiveAlerts()) {
+ mAlertsDeviceModule.stopActiveAlert();
+ } else {
+ Event event = createPlaybackControllerEvent(ApiConstants.Events.PlayCommandIssued.NAME);
+ messageSender.sentEventWithClientContext(event, responseListener);
+ }
+ break;
+ case PAUSE:
+ if (mAlertsDeviceModule.hasActiveAlerts()) {
+ mAlertsDeviceModule.stopActiveAlert();
+ } else {
+ Event event = createPlaybackControllerEvent(ApiConstants.Events.PauseCommandIssued.NAME);
+ messageSender.sentEventWithClientContext(event, responseListener);
+ }
+ break;
+ case PREVIOUS:
+ Event event = createPlaybackControllerEvent(ApiConstants.Events.PreviousCommandIssued.NAME);
+ messageSender.sentEventWithClientContext(event, responseListener);
+ break;
+ case NEXT:
+ Event eventNext = createPlaybackControllerEvent(ApiConstants.Events.NextCommandIssued.NAME);
+ messageSender.sentEventWithClientContext(eventNext, responseListener);
+ break;
+ default:
+ break;
+ }
+ }
+
+ private Event createPlaybackControllerEvent(String name) {
+ Header header = new MessageIdHeader(ApiConstants.NAMESPACE, name);
+ return new Event(header, new Payload());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/screen/ApiConstants.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.screen;
+
+/**
+ * 定义了表示Screen模块的namespace、name,以及其事件、指令的name
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class ApiConstants {
+ public static final String NAMESPACE = "ai.dueros.device_interface.screen";
+ public static final String NAME = "ScreenInterface";
+
+ public static final class Events {
+ public static final class LinkClicked {
+ public static final String NAME = LinkClicked.class.getSimpleName();
+ }
+ }
+
+ public static final class Directives {
+ public static final class HtmlView {
+ public static final String NAME = HtmlView.class.getSimpleName();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/screen/ScreenDeviceModule.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.screen;
+
+import com.baidu.duer.dcs.devicemodule.screen.message.HtmlPayload;
+import com.baidu.duer.dcs.devicemodule.screen.message.LinkClickedPayload;
+import com.baidu.duer.dcs.framework.BaseDeviceModule;
+import com.baidu.duer.dcs.framework.IMessageSender;
+import com.baidu.duer.dcs.framework.message.ClientContext;
+import com.baidu.duer.dcs.framework.message.Directive;
+import com.baidu.duer.dcs.framework.message.Event;
+import com.baidu.duer.dcs.framework.message.Header;
+import com.baidu.duer.dcs.framework.message.MessageIdHeader;
+import com.baidu.duer.dcs.framework.message.Payload;
+import com.baidu.duer.dcs.systeminterface.IWebView;
+
+/**
+ * Screen模块处理并执行服务下发的指令,如HtmlView指令,以及发送事件,如LinkClicked事件
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public class ScreenDeviceModule extends BaseDeviceModule {
+ private final IWebView webView;
+
+ public ScreenDeviceModule(IWebView webView, IMessageSender messageSender) {
+ super(ApiConstants.NAMESPACE, messageSender);
+ this.webView = webView;
+ webView.addWebViewListener(new IWebView.IWebViewListener() {
+ @Override
+ public void onLinkClicked(String url) {
+ sendLinkClickedEvent(url);
+ }
+ });
+ }
+
+ @Override
+ public ClientContext clientContext() {
+ return null;
+ }
+
+ @Override
+ public void handleDirective(Directive directive) {
+ String name = directive.header.getName();
+ if (name.equals(ApiConstants.Directives.HtmlView.NAME)) {
+ handleHtmlPayload(directive.getPayload());
+ }
+ }
+
+ @Override
+ public void release() {
+ }
+
+ private void handleHtmlPayload(Payload payload) {
+ if (payload instanceof HtmlPayload) {
+ HtmlPayload htmlPayload = (HtmlPayload) payload;
+ webView.loadUrl(htmlPayload.getUrl());
+ }
+ }
+
+ private void sendLinkClickedEvent(String url) {
+ String name = ApiConstants.Events.LinkClicked.NAME;
+ Header header = new MessageIdHeader(getNameSpace(), name);
+
+ LinkClickedPayload linkClickedPayload = new LinkClickedPayload(url);
+ Event event = new Event(header, linkClickedPayload);
+ if (messageSender != null) {
+ messageSender.sendEvent(event);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/screen/message/HtmlPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.screen.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+import java.io.Serializable;
+
+/**
+ * HtmlView指令对应的payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/5.
+ */
+public class HtmlPayload extends Payload implements Serializable {
+ private String url;
+ private String token;
+
+ public HtmlPayload() {
+ }
+
+ public HtmlPayload(String url, String token) {
+ this.url = url;
+ this.token = token;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public String getToken() {
+ return token;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/screen/message/LinkClickedPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.screen.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * LinkClicked事件对应的payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/5.
+ */
+public class LinkClickedPayload extends Payload {
+ private String url;
+
+ public LinkClickedPayload(String url) {
+ this.url = url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/speakcontroller/ApiConstants.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.speakcontroller;
+
+/**
+ * 定义了表示SpeakController模块的namespace、name,以及其事件、指令的name
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class ApiConstants {
+ public static final String NAMESPACE = "ai.dueros.device_interface.speaker_controller";
+ public static final String NAME = "SpeakerControllerInterface";
+
+ public static final class Events {
+ public static final class VolumeChanged {
+ public static final String NAME = VolumeChanged.class.getSimpleName();
+ }
+
+ public static final class MuteChanged {
+ public static final String NAME = MuteChanged.class.getSimpleName();
+ }
+
+ public static final class VolumeState {
+ public static final String NAME = VolumeState.class.getSimpleName();
+ }
+ }
+
+ public static final class Directives {
+ public static final class SetVolume {
+ public static final String NAME = SetVolume.class.getSimpleName();
+ }
+
+ public static final class AdjustVolume {
+ public static final String NAME = AdjustVolume.class.getSimpleName();
+ }
+
+ public static final class SetMute {
+ public static final String NAME = SetMute.class.getSimpleName();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/speakcontroller/SpeakerControllerDeviceModule.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.speakcontroller;
+
+import com.baidu.duer.dcs.devicemodule.speakcontroller.message.AdjustVolumePayload;
+import com.baidu.duer.dcs.devicemodule.speakcontroller.message.MuteChangedPayload;
+import com.baidu.duer.dcs.devicemodule.speakcontroller.message.SetMutePayload;
+import com.baidu.duer.dcs.devicemodule.speakcontroller.message.SetVolumePayload;
+import com.baidu.duer.dcs.devicemodule.speakcontroller.message.VolumeStatePayload;
+import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException;
+import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException.ExceptionType;
+import com.baidu.duer.dcs.framework.BaseDeviceModule;
+import com.baidu.duer.dcs.framework.BaseMultiChannelMediaPlayer;
+import com.baidu.duer.dcs.framework.IMessageSender;
+import com.baidu.duer.dcs.framework.message.ClientContext;
+import com.baidu.duer.dcs.framework.message.Directive;
+import com.baidu.duer.dcs.framework.message.Event;
+import com.baidu.duer.dcs.framework.message.Header;
+import com.baidu.duer.dcs.framework.message.MessageIdHeader;
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * SpeakerController模块处理服务下发的SetVolume、AdjustVolume、SetMute指令,发送VolumeChanged、MuteChanged事件,
+ * 以及维护自身的端状态
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public class SpeakerControllerDeviceModule extends BaseDeviceModule {
+ private final BaseMultiChannelMediaPlayer.ISpeakerController speakerController;
+
+ public SpeakerControllerDeviceModule(BaseMultiChannelMediaPlayer.ISpeakerController speakerController,
+ IMessageSender messageSender) {
+ super(ApiConstants.NAMESPACE, messageSender);
+ this.speakerController = speakerController;
+ }
+
+ @Override
+ public ClientContext clientContext() {
+ String namespace = getNameSpace();
+ String name = ApiConstants.Events.VolumeState.NAME;
+ Header header = new Header(namespace, name);
+ long volume = (long) (speakerController.getVolume() * 100.0F);
+ boolean mute = speakerController.getMute();
+ VolumeStatePayload payload = new VolumeStatePayload(volume, mute);
+ return new ClientContext(header, payload);
+ }
+
+ @Override
+ public void handleDirective(Directive directive) throws HandleDirectiveException {
+ Header header = directive.header;
+ String name = header.getName();
+ Payload payload = directive.getPayload();
+ if (name.equals(ApiConstants.Directives.AdjustVolume.NAME)) {
+ if (payload instanceof AdjustVolumePayload) {
+ AdjustVolumePayload adjustVolumePayload = (AdjustVolumePayload) directive.getPayload();
+ float increment = (float) adjustVolumePayload.getVolume() / 100.0F;
+ float volume = speakerController.getVolume() + increment;
+ volume = Math.min(1.0F, Math.max(volume, -1.0F));
+ setVolume(volume);
+ }
+ } else if (name.equals(ApiConstants.Directives.SetVolume.NAME)) {
+ if (payload instanceof SetVolumePayload) {
+ SetVolumePayload setVolumePayload = (SetVolumePayload) payload;
+ float volume = (float) setVolumePayload.getVolume() / 100.0F;
+ this.setVolume(volume);
+ }
+ } else if (name.equals(ApiConstants.Directives.SetMute.NAME)) {
+ if (payload instanceof SetMutePayload) {
+ SetMutePayload setMutePayload = (SetMutePayload) payload;
+ setMute(setMutePayload.getMute());
+ }
+ } else {
+ String message = "SpeakerController cannot handle the directive";
+ throw new HandleDirectiveException(ExceptionType.UNSUPPORTED_OPERATION, message);
+ }
+ }
+
+ @Override
+ public void release() {
+
+ }
+
+ private void setVolume(float volume) {
+ speakerController.setVolume(volume);
+ messageSender.sendEvent(volumeChangedEvent());
+ }
+
+ private void setMute(boolean mute) {
+ speakerController.setMute(mute);
+ messageSender.sendEvent(muteChangedEvent());
+ }
+
+ private Event volumeChangedEvent() {
+ String nameSpace = getNameSpace();
+ String name = ApiConstants.Events.VolumeChanged.NAME;
+ MessageIdHeader header = new MessageIdHeader(nameSpace, name);
+ VolumeStatePayload payload = new VolumeStatePayload(getVolume(), isMuted());
+ return new Event(header, payload);
+ }
+
+ private Event muteChangedEvent() {
+ String nameSpace = getNameSpace();
+ String name = ApiConstants.Events.MuteChanged.NAME;
+ MessageIdHeader header = new MessageIdHeader(nameSpace, name);
+ MuteChangedPayload payload = new MuteChangedPayload(getVolume(), isMuted());
+ return new Event(header, payload);
+ }
+
+ private long getVolume() {
+ return (long) (speakerController.getVolume() * 100.0F);
+ }
+
+ private boolean isMuted() {
+ return speakerController.getMute();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/speakcontroller/message/AdjustVolumePayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.speakcontroller.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * adjustVolume指令对应的Payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/5.
+ */
+public class AdjustVolumePayload extends Payload {
+ private long volume;
+
+ public AdjustVolumePayload() {
+ }
+
+ public AdjustVolumePayload(long volume) {
+ this.volume = volume;
+ }
+
+ public void setVolume(long volume) {
+ this.volume = volume;
+ }
+
+ public long getVolume() {
+ return volume;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/speakcontroller/message/MuteChangedPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.speakcontroller.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * 上报MuteChanged事件对应的Payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/5.
+ */
+public class MuteChangedPayload extends Payload {
+ private long volume;
+ private boolean muted;
+
+ public MuteChangedPayload(long volume, boolean muted) {
+ this.volume = volume;
+ this.muted = muted;
+ }
+
+ public void setVolume(long volume) {
+ this.volume = volume;
+ }
+
+ public long getVolume() {
+ return this.volume;
+ }
+
+ public void setMuted(boolean muted) {
+ this.muted = muted;
+ }
+
+ public boolean getMuted() {
+ return muted;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/speakcontroller/message/SetMutePayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.speakcontroller.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * setMuted指令对应的Payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/5.
+ */
+public class SetMutePayload extends Payload {
+ private boolean mute;
+
+ public SetMutePayload() {
+ }
+
+ public SetMutePayload(boolean mute) {
+ this.mute = mute;
+ }
+
+ public void setMute(boolean mute) {
+ this.mute = mute;
+ }
+
+ public boolean getMute() {
+ return this.mute;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/speakcontroller/message/SetVolumePayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.speakcontroller.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * setVolume指令对应的Payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/5.
+ */
+public class SetVolumePayload extends Payload {
+ private long volume;
+
+ public SetVolumePayload() {
+ }
+
+ public SetVolumePayload(long volume) {
+ this.volume = volume;
+ }
+
+ public void setVolume(long volume) {
+ this.volume = volume;
+ }
+
+ public long getVolume() {
+ return volume;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/speakcontroller/message/VolumeStatePayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.speakcontroller.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * 本模块端状态对应的Payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/5.
+ */
+public class VolumeStatePayload extends Payload {
+ private long volume;
+ private boolean muted;
+
+ public VolumeStatePayload() {
+ }
+
+ public VolumeStatePayload(long volume, boolean muted) {
+ this.volume = volume;
+ this.muted = muted;
+ }
+
+ public void setVolume(long volume) {
+ this.volume = volume;
+ }
+
+ public long getVolume() {
+ return this.volume;
+ }
+
+ public void setMuted(boolean muted) {
+ this.muted = muted;
+ }
+
+ public boolean getMuted() {
+ return muted;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/system/ApiConstants.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.system;
+
+/**
+ * 定义了表示System模块的namespace、name,以及其事件、指令、异常的name
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class ApiConstants {
+ public static final String NAMESPACE = "ai.dueros.device_interface.system";
+ public static final String NAME = "SystemInterface";
+
+ public static final class Events {
+ public static final class SynchronizeState {
+ public static final String NAME = SynchronizeState.class.getSimpleName();
+ }
+
+ public static final class ExceptionEncountered {
+ public static final String NAME = ExceptionEncountered.class.getSimpleName();
+ }
+
+ public static final class UserInactivityReport {
+ public static final String NAME = UserInactivityReport.class.getSimpleName();
+ }
+ }
+
+ public static final class Directives {
+ public static final class ResetUserInactivity {
+ public static final String NAME = ResetUserInactivity.class.getSimpleName();
+ }
+
+ public static final class SetEndpoint {
+ public static final String NAME = SetEndpoint.class.getSimpleName();
+ }
+
+ public static final class ThrowException {
+ public static final String NAME = ThrowException.class.getSimpleName();
+ }
+ }
+
+ public static final class Exception {
+ public static final String NAME = Exception.class.getSimpleName();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/system/HandleDirectiveException.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.system;
+
+/**
+ * 指令没有处理异常
+ * <p>
+ * Created by wuruisheng on 2017/6/3.
+ */
+public class HandleDirectiveException extends Exception {
+ private ExceptionType exceptionType;
+
+ public HandleDirectiveException(ExceptionType exceptionType, String message) {
+ super(message);
+ this.exceptionType = exceptionType;
+ }
+
+ public ExceptionType getExceptionType() {
+ return exceptionType;
+ }
+
+ public enum ExceptionType {
+ UNEXPECTED_INFORMATION_RECEIVED,
+ UNSUPPORTED_OPERATION,
+ INTERNAL_ERROR
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/system/SystemDeviceModule.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.system;
+
+import com.baidu.duer.dcs.devicemodule.system.message.ExceptionEncounteredPayload;
+import com.baidu.duer.dcs.devicemodule.system.message.SetEndPointPayload;
+import com.baidu.duer.dcs.devicemodule.system.message.ThrowExceptionPayload;
+import com.baidu.duer.dcs.devicemodule.system.message.UserInactivityReportPayload;
+import com.baidu.duer.dcs.framework.BaseDeviceModule;
+import com.baidu.duer.dcs.framework.IMessageSender;
+import com.baidu.duer.dcs.framework.message.ClientContext;
+import com.baidu.duer.dcs.framework.message.Directive;
+import com.baidu.duer.dcs.framework.message.Event;
+import com.baidu.duer.dcs.framework.message.Header;
+import com.baidu.duer.dcs.framework.message.MessageIdHeader;
+import com.baidu.duer.dcs.framework.message.Payload;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ * System模块处理ResetUserInactivity、SetEndpoint、ThrowException指令,发送SynchronizeState、UserInactivityReport等事件
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public class SystemDeviceModule extends BaseDeviceModule {
+ private final ScheduledExecutorService scheduledExecutor = Executors.newScheduledThreadPool(1);
+ private static final long MILLISECONDS_PER_SECOND = 1000;
+ private static final long USER_INACTIVITY_REPORT_PERIOD_HOURS = 1;
+ private final List<IDeviceModuleListener> deviceModuleListeners;
+ private AtomicLong lastUserInteractionInSeconds;
+ private Provider provider;
+
+ public SystemDeviceModule(final IMessageSender messageSender) {
+ super(ApiConstants.NAMESPACE, messageSender);
+
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ long inactiveTimeInSeconds = currentTimeSeconds() - lastUserInteractionInSeconds.get();
+ Event event = userInactivityReportEvent(inactiveTimeInSeconds);
+ messageSender.sendEvent(event);
+ }
+ };
+
+ lastUserInteractionInSeconds = new AtomicLong(currentTimeSeconds());
+ scheduledExecutor.scheduleAtFixedRate(runnable, USER_INACTIVITY_REPORT_PERIOD_HOURS,
+ USER_INACTIVITY_REPORT_PERIOD_HOURS, TimeUnit.HOURS);
+
+ deviceModuleListeners = Collections.synchronizedList(new ArrayList<IDeviceModuleListener>());
+ }
+
+
+ @Override
+ public ClientContext clientContext() {
+ return null;
+ }
+
+ @Override
+ public void handleDirective(Directive directive) throws HandleDirectiveException {
+ String name = directive.header.getName();
+ if (ApiConstants.Directives.ResetUserInactivity.NAME.equals(name)) {
+ userActivity();
+ } else if (ApiConstants.Directives.SetEndpoint.NAME.equals(name)) {
+ handleSetEndpointDirective(directive);
+ } else if (ApiConstants.Directives.ThrowException.NAME.equals(name)) {
+ handleThrowException(directive);
+ } else {
+ String message = "system cannot handle this directive";
+ throw (new HandleDirectiveException(
+ HandleDirectiveException.ExceptionType.UNSUPPORTED_OPERATION, message));
+ }
+ }
+
+ @Override
+ public void release() {
+ if (!scheduledExecutor.isShutdown()) {
+ scheduledExecutor.shutdownNow();
+ }
+ deviceModuleListeners.clear();
+ }
+
+ private void handleSetEndpointDirective(Directive directive) {
+ Payload payload = directive.getPayload();
+ if (payload instanceof SetEndPointPayload) {
+ SetEndPointPayload setEndPointPayload = (SetEndPointPayload) payload;
+ fireSetEndpoint(setEndPointPayload);
+ }
+ }
+
+ private void handleThrowException(Directive directive) {
+ Payload payload = directive.getPayload();
+ if (payload instanceof ThrowExceptionPayload) {
+ ThrowExceptionPayload throwExceptionPayload = (ThrowExceptionPayload) payload;
+ fireThrowException(throwExceptionPayload);
+ }
+ }
+
+ public void sendSynchronizeStateEvent() {
+ String name = ApiConstants.Events.SynchronizeState.NAME;
+ Header header = new MessageIdHeader(getNameSpace(), name);
+ Payload payload = new Payload();
+ Event event = new Event(header, payload);
+
+ if (messageSender != null) {
+ messageSender.sentEventWithClientContext(event, null);
+ }
+ }
+
+ private Event userInactivityReportEvent(long inactiveTimeInSeconds) {
+ final String name = ApiConstants.Events.UserInactivityReport.NAME;
+ Header header = new MessageIdHeader(getNameSpace(), name);
+ Payload payload = new UserInactivityReportPayload(inactiveTimeInSeconds);
+ Event event = new Event(header, payload);
+ return event;
+ }
+
+ public void sendExceptionEncounteredEvent(String directiveJson,
+ HandleDirectiveException.ExceptionType type,
+ String message) {
+ final String name = ApiConstants.Events.ExceptionEncountered.NAME;
+ Header header = new MessageIdHeader(getNameSpace(), name);
+
+ ExceptionEncounteredPayload exceptionEncounteredPayLoad = new ExceptionEncounteredPayload(
+ directiveJson, type, message);
+ Event event = new Event(header, exceptionEncounteredPayLoad);
+ messageSender.sentEventWithClientContext(event, null);
+ }
+
+ private void userActivity() {
+ lastUserInteractionInSeconds.set(currentTimeSeconds());
+ }
+
+ private long currentTimeSeconds() {
+ return System.currentTimeMillis() / MILLISECONDS_PER_SECOND;
+ }
+
+ public Provider getProvider() {
+ if (provider == null) {
+ provider = new Provider();
+ }
+
+ return provider;
+ }
+
+ public class Provider {
+ public void userActivity() {
+ SystemDeviceModule.this.userActivity();
+ }
+ }
+
+ private void fireSetEndpoint(SetEndPointPayload setEndPointPayload) {
+ for (IDeviceModuleListener listener : deviceModuleListeners) {
+ listener.onSetEndpoint(setEndPointPayload);
+ }
+ }
+
+ private void fireThrowException(ThrowExceptionPayload throwExceptionPayload) {
+ for (IDeviceModuleListener listener : deviceModuleListeners) {
+ listener.onThrowException(throwExceptionPayload);
+ }
+ }
+
+ public void addModuleListener(IDeviceModuleListener listener) {
+ deviceModuleListeners.add(listener);
+ }
+
+ public interface IDeviceModuleListener {
+ void onSetEndpoint(SetEndPointPayload endPointPayload);
+
+ void onThrowException(ThrowExceptionPayload throwExceptionPayload);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/system/message/ExceptionEncounteredPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.system.message;
+
+import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException.ExceptionType;
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * ExceptionEncountered事件对应的payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/3.
+ */
+public class ExceptionEncounteredPayload extends Payload {
+ private String unparsedDirective;
+ private Error error;
+
+ public ExceptionEncounteredPayload(String unparsedDirective, ExceptionType type, String message) {
+ this.unparsedDirective = unparsedDirective;
+ Error error = new Error(type, message);
+ this.error = error;
+ }
+
+ public void setUnparsedDirective(String unparsedDirective) {
+ this.unparsedDirective = unparsedDirective;
+ }
+
+ public String getUnparsedDirective() {
+ return unparsedDirective;
+ }
+
+ public void setError(Error error) {
+ this.error = error;
+ }
+
+ public Error getError() {
+ return error;
+ }
+
+ public static class Error {
+ public ExceptionType type;
+ public String message;
+
+ public Error(ExceptionType type, String message) {
+ this.type = type;
+ this.message = message;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/system/message/SetEndPointPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.system.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * setEndPoint指令对应的payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/3.
+ */
+public class SetEndPointPayload extends Payload {
+ private String endpoint;
+
+ public SetEndPointPayload() {
+
+ }
+
+ public SetEndPointPayload(String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public void setEndpoint(String endpoint) {
+ this.endpoint = endpoint;
+ }
+
+ public String getEndpoint() {
+ return endpoint;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/system/message/ThrowExceptionPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.system.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * ThrowException指令对应的payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/8.
+ */
+public class ThrowExceptionPayload extends Payload {
+ private String code;
+ private String description;
+
+ public ThrowExceptionPayload() {
+ }
+
+ public ThrowExceptionPayload(String code, String description) {
+ this.code = code;
+ this.description = description;
+ }
+
+ public void setCode(String code) {
+ this.code = code;
+ }
+
+ public String getCode() {
+ return this.code;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ @Override
+ public String toString() {
+ return "code=" + code + " description=" + description;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/system/message/UserInactivityReportPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.system.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * UserInactivityReport事件对应的payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/3.
+ */
+public class UserInactivityReportPayload extends Payload {
+ private long inactiveTimeInSeconds;
+
+ public UserInactivityReportPayload(long inactiveTimeInSeconds) {
+ this.inactiveTimeInSeconds = inactiveTimeInSeconds;
+ }
+
+ void setInactiveTimeInSeconds(long inactiveTimeInSeconds) {
+ this.inactiveTimeInSeconds = inactiveTimeInSeconds;
+ }
+
+ long getInactiveTimeInSeconds() {
+ return inactiveTimeInSeconds;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/voiceinput/ApiConstants.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.voiceinput;
+
+/**
+ * 定义了表示Voice Input模块的namespace、name,以及其事件、指令的name
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class ApiConstants {
+ public static final String NAMESPACE = "ai.dueros.device_interface.voice_input";
+ public static final String NAME = "VoiceInputInterface";
+
+ public static final class Events {
+ public static final class ListenStarted {
+ public static final String NAME = ListenStarted.class.getSimpleName();
+ }
+
+ public static final class ListenTimedOut {
+ public static final String NAME = ListenTimedOut.class.getSimpleName();
+ }
+ }
+
+ public static final class Directives {
+ public static final class Listen {
+ public static final String NAME = Listen.class.getSimpleName();
+ }
+
+ public static final class StopListen {
+ public static final String NAME = StopListen.class.getSimpleName();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/voiceinput/VoiceInputDeviceModule.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,198 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.voiceinput;
+
+import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException;
+import com.baidu.duer.dcs.devicemodule.voiceinput.message.ListenStartedPayload;
+import com.baidu.duer.dcs.framework.BaseDeviceModule;
+import com.baidu.duer.dcs.framework.DcsResponseDispatcher;
+import com.baidu.duer.dcs.framework.DialogRequestIdHandler;
+import com.baidu.duer.dcs.framework.IMessageSender;
+import com.baidu.duer.dcs.framework.IResponseListener;
+import com.baidu.duer.dcs.framework.message.ClientContext;
+import com.baidu.duer.dcs.framework.message.DcsStreamRequestBody;
+import com.baidu.duer.dcs.framework.message.DialogRequestIdHeader;
+import com.baidu.duer.dcs.framework.message.Directive;
+import com.baidu.duer.dcs.framework.message.Event;
+import com.baidu.duer.dcs.framework.message.Payload;
+import com.baidu.duer.dcs.systeminterface.IAudioInput;
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Voice Input模块处理并执行服务下发的StopListen、Listen指令,上报ListenStarted、ListenTimedOut事件
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public class VoiceInputDeviceModule extends BaseDeviceModule {
+ public static final String TAG = VoiceInputDeviceModule.class.getSimpleName();
+ private final IAudioInput audioInput;
+ private final List<IVoiceInputListener> voiceInputListeners;
+ private final IMediaPlayer mediaPlayer;
+ private final DialogRequestIdHandler dialogRequestIdHandler;
+ private final DcsResponseDispatcher dcsResponseDispatcher;
+
+ public VoiceInputDeviceModule(final IMediaPlayer mediaPlayer,
+ IMessageSender messageSender,
+ final IAudioInput audioInput,
+ DialogRequestIdHandler dialogRequestIdHandler,
+ DcsResponseDispatcher dcsResponseDispatcher) {
+ super(ApiConstants.NAMESPACE, messageSender);
+ this.audioInput = audioInput;
+ this.voiceInputListeners = Collections.synchronizedList(new ArrayList<IVoiceInputListener>());
+ this.mediaPlayer = mediaPlayer;
+ this.dialogRequestIdHandler = dialogRequestIdHandler;
+ this.dcsResponseDispatcher = dcsResponseDispatcher;
+
+ this.audioInput.registerAudioInputListener(new IAudioInput.IAudioInputListener() {
+ @Override
+ public void onStartRecord(DcsStreamRequestBody dcsStreamRequestBody) {
+ stopSpeaker();
+ // 发送网络请求
+ sendListenStartedEvent(dcsStreamRequestBody, new IResponseListener() {
+ @Override
+ public void onSucceed(int statusCode) {
+ fireOnSucceed(statusCode);
+ // 没有下发新的语音speak-stream
+ if (statusCode == 204) {
+ // 设置对话通道为非活跃状态
+ mediaPlayer.setActive(false);
+ } else {
+ mediaPlayer.setActive(true);
+ }
+ }
+
+ @Override
+ public void onFailed(String errorMessage) {
+ LogUtil.d(TAG, "onFailed,errorMessage:" + errorMessage);
+ fireOnFailed(errorMessage);
+ audioInput.stopRecord();
+ mediaPlayer.setActive(false);
+ }
+ });
+
+ fireOnStartRecord();
+ }
+
+ @Override
+ public void onStopRecord() {
+ fireFinishRecord();
+ }
+ });
+ }
+
+
+ @Override
+ public ClientContext clientContext() {
+ return null;
+ }
+
+ @Override
+ public void handleDirective(Directive directive) throws HandleDirectiveException {
+ String name = directive.getName();
+ if (name.equals(ApiConstants.Directives.StopListen.NAME)) {
+ audioInput.stopRecord();
+ } else if (name.equals(ApiConstants.Directives.Listen.NAME)) {
+ audioInput.startRecord();
+ } else {
+ String message = "No device to handle the directive";
+ throw new HandleDirectiveException(
+ HandleDirectiveException.ExceptionType.UNSUPPORTED_OPERATION,
+ message);
+ }
+ }
+
+ @Override
+ public void release() {
+ voiceInputListeners.clear();
+ }
+
+ /**
+ * 停止speaker对话通道的语音播放
+ */
+ private void stopSpeaker() {
+ mediaPlayer.setActive(true);
+ mediaPlayer.stop();
+ dcsResponseDispatcher.interruptDispatch();
+ }
+
+ private void sendListenStartedEvent(DcsStreamRequestBody streamRequestBody, IResponseListener responseListener) {
+ String dialogRequestId = dialogRequestIdHandler.createActiveDialogRequestId();
+ String name = ApiConstants.Events.ListenStarted.NAME;
+ DialogRequestIdHeader header = new DialogRequestIdHeader(getNameSpace(), name, dialogRequestId);
+ Payload payload = new ListenStartedPayload(ListenStartedPayload.FORMAT);
+ Event event = new Event(header, payload);
+ messageSender.sendEvent(event, streamRequestBody, responseListener);
+ }
+
+ private void fireOnStartRecord() {
+ for (IVoiceInputListener listener : voiceInputListeners) {
+ listener.onStartRecord();
+ }
+ }
+
+ private void fireFinishRecord() {
+ for (IVoiceInputListener listener : voiceInputListeners) {
+ listener.onFinishRecord();
+ }
+ }
+
+ private void fireOnSucceed(int statusCode) {
+ for (IVoiceInputListener listener : voiceInputListeners) {
+ listener.onSucceed(statusCode);
+ }
+ }
+
+ private void fireOnFailed(String errorMessage) {
+ for (IVoiceInputListener listener : voiceInputListeners) {
+ listener.onFailed(errorMessage);
+ }
+ }
+
+ public void addVoiceInputListener(IVoiceInputListener listener) {
+ this.voiceInputListeners.add(listener);
+ }
+
+ public interface IVoiceInputListener {
+ /**
+ * 开始录音的回调
+ */
+ void onStartRecord();
+
+ /**
+ * 结束录音的回调
+ */
+ void onFinishRecord();
+
+ /**
+ * 录音-网络请求成功
+ *
+ * @param statusCode 网络返回状态码
+ */
+ void onSucceed(int statusCode);
+
+ /**
+ * 录音-网络请求失败
+ *
+ * @param errorMessage 错误信息
+ */
+ void onFailed(String errorMessage);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/voiceinput/message/ListenPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.voiceinput.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * Listen指令对应的payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class ListenPayload extends Payload {
+ private long timeoutInMilliseconds;
+
+ public void setTimeoutInMilliseconds(long timeoutInMilliseconds) {
+ this.timeoutInMilliseconds = timeoutInMilliseconds;
+ }
+
+ public long getTimeoutInMilliseconds() {
+ return timeoutInMilliseconds;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/voiceinput/message/ListenStartedPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.voiceinput.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * ListenStarted事件对应的payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class ListenStartedPayload extends Payload {
+ public static final String FORMAT = "AUDIO_L16_RATE_16000_CHANNELS_1";
+ private String format;
+
+ public ListenStartedPayload(String format) {
+ this.format = format;
+ }
+
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ public String getFormat() {
+ return format;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/voiceoutput/ApiConstants.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.voiceoutput;
+
+/**
+ * 定义了表示Voice Output模块的namespace、name,以及其事件、指令的name
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/1.
+ */
+public class ApiConstants {
+ public static final String NAMESPACE = "ai.dueros.device_interface.voice_output";
+ public static final String NAME = "VoiceOutputInterface";
+
+ public static final class Events {
+ public static final class SpeechStarted {
+ public static final String NAME = SpeechStarted.class.getSimpleName();
+ }
+
+ public static final class SpeechFinished {
+ public static final String NAME = SpeechFinished.class.getSimpleName();
+ }
+
+ public static final class SpeechState {
+ public static final String NAME = SpeechState.class.getSimpleName();
+ }
+ }
+
+ public static final class Directives {
+ public static final class Speak {
+ public static final String NAME = Speak.class.getSimpleName();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/voiceoutput/VoiceOutputDeviceModule.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.voiceoutput;
+
+import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException;
+import com.baidu.duer.dcs.devicemodule.voiceoutput.message.SpeakPayload;
+import com.baidu.duer.dcs.devicemodule.voiceoutput.message.SpeechLifecyclePayload;
+import com.baidu.duer.dcs.devicemodule.voiceoutput.message.VoiceOutputStatePayload;
+import com.baidu.duer.dcs.framework.BaseDeviceModule;
+import com.baidu.duer.dcs.framework.IMessageSender;
+import com.baidu.duer.dcs.framework.IResponseListener;
+import com.baidu.duer.dcs.framework.message.ClientContext;
+import com.baidu.duer.dcs.framework.message.Directive;
+import com.baidu.duer.dcs.framework.message.Event;
+import com.baidu.duer.dcs.framework.message.Header;
+import com.baidu.duer.dcs.framework.message.MessageIdHeader;
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Voice Output模块处理并执行服务下发的Speak指令,上报SpeechStarted、SpeechFinished事件,以及维护自身的端状态
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/31.
+ */
+public class VoiceOutputDeviceModule extends BaseDeviceModule {
+ private static final String TAG = VoiceOutputDeviceModule.class.getSimpleName();
+ // 播放回调
+ private final List<IVoiceOutputListener> voiceOutputListeners;
+ // 播放队列
+ private final LinkedList<SpeakPayload> speakQueue = new LinkedList<>();
+ // 语音播放的播放器
+ private final IMediaPlayer mediaPlayer;
+ private SpeechState speechState = SpeechState.FINISHED;
+
+ // 上一次的token
+ private String lastSpeakToken = "";
+
+ // 当前播放状态
+ private enum SpeechState {
+ PLAYING,
+ FINISHED
+ }
+
+ public VoiceOutputDeviceModule(IMediaPlayer mediaPlayer,
+ IMessageSender messageSender) {
+ super(ApiConstants.NAMESPACE, messageSender);
+ this.mediaPlayer = mediaPlayer;
+ this.mediaPlayer.addMediaPlayerListener(mediaPlayerListener);
+ this.voiceOutputListeners = Collections.synchronizedList(new ArrayList<IVoiceOutputListener>());
+ }
+
+ @Override
+ public ClientContext clientContext() {
+ String namespace = ApiConstants.NAMESPACE;
+ String name = ApiConstants.Events.SpeechState.NAME;
+ Header header = new Header(namespace, name);
+ VoiceOutputStatePayload payload = new VoiceOutputStatePayload(lastSpeakToken,
+ mediaPlayer.getCurrentPosition(),
+ speechState.name());
+ return new ClientContext(header, payload);
+ }
+
+ @Override
+ public void handleDirective(Directive directive) throws HandleDirectiveException {
+ String directiveName = directive.getName();
+ LogUtil.d(TAG, "rawMessage:" + directive.rawMessage);
+ LogUtil.d(TAG, "directiveName:" + directiveName);
+ if (directiveName.equals(ApiConstants.Directives.Speak.NAME)) {
+ SpeakPayload speak = (SpeakPayload) directive.payload;
+ handleSpeak(speak);
+ } else {
+ String message = "VoiceOutput cannot handle the directive";
+ throw (new HandleDirectiveException(
+ HandleDirectiveException.ExceptionType.UNSUPPORTED_OPERATION, message));
+ }
+ }
+
+ private void handleSpeak(SpeakPayload speak) {
+ speakQueue.add(speak);
+ // 如果已经有了,就只入队列,等待下一次的调度
+ if (speakQueue.size() == 1) {
+ startSpeech();
+ }
+ }
+
+ private void startSpeech() {
+ final SpeakPayload speak = speakQueue.getFirst();
+ if (null != speak) {
+ lastSpeakToken = speak.token;
+ InputStream inputStream = new ByteArrayInputStream(speak.attachedContent);
+ mediaPlayer.play(new IMediaPlayer.MediaResource(inputStream));
+ }
+ }
+
+ private IMediaPlayer.IMediaPlayerListener mediaPlayerListener = new IMediaPlayer.SimpleMediaPlayerListener() {
+ @Override
+ public void onPrepared() {
+ super.onPrepared();
+ speechState = SpeechState.PLAYING;
+ sendStartedEvent(lastSpeakToken);
+ fireOnVoiceOutputStarted();
+ }
+
+ @Override
+ public void onStopped() {
+ super.onStopped();
+ speakQueue.clear();
+ }
+
+ @Override
+ public void onError(String error, IMediaPlayer.ErrorType errorType) {
+ super.onError(error, errorType);
+ finishedSpeechItem();
+ }
+
+ @Override
+ public void onCompletion() {
+ LogUtil.d(TAG, " IMediaPlayer onCompletion");
+ finishedSpeechItem();
+ }
+ };
+
+ /**
+ * 播放完一条后开始下一条的处理
+ */
+ private void finishedSpeechItem() {
+ speakQueue.poll();
+ LogUtil.d(TAG, "finishedSpeechItem speakQueue size :" + speakQueue.size());
+ if (speakQueue.isEmpty()) {
+ speechState = SpeechState.FINISHED;
+ sendFinishedEvent(lastSpeakToken);
+ fireOnVoiceOutputFinished();
+ } else {
+ startSpeech();
+ }
+ }
+
+ @Override
+ public void release() {
+ if (mediaPlayer != null) {
+ mediaPlayer.release();
+ mediaPlayer.removeMediaPlayerListener(mediaPlayerListener);
+ }
+ if (isSpeaking()) {
+ speechState = SpeechState.FINISHED;
+ }
+ speakQueue.clear();
+ voiceOutputListeners.clear();
+ }
+
+ public boolean isSpeaking() {
+ return speechState == SpeechState.PLAYING;
+ }
+
+ /**
+ * 播放开始时上报的事件
+ *
+ * @param token token 一条speak的唯一标识
+ */
+ private void sendStartedEvent(String token) {
+ String namespace = ApiConstants.NAMESPACE;
+ String name = ApiConstants.Events.SpeechStarted.NAME;
+ MessageIdHeader header = new MessageIdHeader(namespace, name);
+ Event event = new Event(header, new SpeechLifecyclePayload(token));
+ messageSender.sendEvent(event);
+ }
+
+ /**
+ * 播放结束时上报的事件
+ *
+ * @param token token 一条speak的唯一标识
+ */
+ private void sendFinishedEvent(String token) {
+ String namespace = ApiConstants.NAMESPACE;
+ String name = ApiConstants.Events.SpeechFinished.NAME;
+ MessageIdHeader header = new MessageIdHeader(namespace, name);
+ Event event = new Event(header, new SpeechLifecyclePayload(token));
+ messageSender.sendEvent(event, new IResponseListener() {
+ @Override
+ public void onSucceed(int statusCode) {
+ // 没有新的语音speak-stream
+ if (statusCode == 204) {
+ mediaPlayer.setActive(false);
+ } else {
+ mediaPlayer.setActive(true);
+ }
+ }
+
+ @Override
+ public void onFailed(String errorMessage) {
+ mediaPlayer.setActive(false);
+ }
+ });
+ }
+
+ private void fireOnVoiceOutputStarted() {
+ for (IVoiceOutputListener listener : voiceOutputListeners) {
+ listener.onVoiceOutputStarted();
+ }
+ }
+
+ private void fireOnVoiceOutputFinished() {
+ for (IVoiceOutputListener listener : voiceOutputListeners) {
+ listener.onVoiceOutputFinished();
+ }
+ }
+
+ /**
+ * 添加播放监听
+ *
+ * @param listener listener
+ */
+ public void addVoiceOutputListener(IVoiceOutputListener listener) {
+ this.voiceOutputListeners.add(listener);
+ }
+
+ /**
+ * 播报监听器接口
+ */
+ public interface IVoiceOutputListener {
+ /**
+ * 开始播放时回调
+ */
+ void onVoiceOutputStarted();
+
+ /**
+ * 播放完成时回调
+ */
+ void onVoiceOutputFinished();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/voiceoutput/message/SpeakPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.voiceoutput.message;
+
+import com.baidu.duer.dcs.framework.message.AttachedContentPayload;
+import com.baidu.duer.dcs.framework.message.Payload;
+
+import org.codehaus.jackson.annotate.JsonIgnore;
+
+/**
+ * Speak指令对应的payload结构
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class SpeakPayload extends Payload implements AttachedContentPayload {
+ public String url;
+ public String format;
+ public String token;
+
+ @JsonIgnore
+ public byte[] attachedContent;
+
+ // start with cid:
+ public void setUrl(String url) {
+ this.url = url.substring(4);
+ }
+
+ @Override
+ public boolean requiresAttachedContent() {
+ return !hasAttachedContent();
+ }
+
+ @Override
+ public boolean hasAttachedContent() {
+ return attachedContent != null;
+ }
+
+ @Override
+ public String getAttachedContentId() {
+ return url;
+ }
+
+ @Override
+ public byte[] getAttachedContent() {
+ return attachedContent;
+ }
+
+ @Override
+ public void setAttachedContent(String cid, byte[] data) {
+ if (getAttachedContentId().equals(cid)) {
+ this.attachedContent = data;
+ } else {
+ throw new IllegalArgumentException(
+ "Tried to add the wrong audio content to a Speak directive. This cid: "
+ + getAttachedContentId() + " other cid: " + cid);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/voiceoutput/message/SpeechLifecyclePayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.voiceoutput.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+/**
+ * SpeechStarted和SpeechFinished事件对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/1.
+ */
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+public class SpeechLifecyclePayload extends Payload {
+ private String token;
+
+ public SpeechLifecyclePayload(String token) {
+ this.token = token;
+ }
+
+ public void setToken(String token) {
+ this.token = token;
+ }
+
+ public String getToken() {
+ return token;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/devicemodule/voiceoutput/message/VoiceOutputStatePayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.devicemodule.voiceoutput.message;
+
+import com.baidu.duer.dcs.framework.message.Payload;
+
+/**
+ * 本模块端状态对应的payload结构
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/31.
+ */
+public class VoiceOutputStatePayload extends Payload {
+ public String token;
+ public long offsetInMilliseconds;
+ public String playerActivity;
+
+ public VoiceOutputStatePayload(String token, long offsetInMilliseconds, String playerActivity) {
+ this.token = token;
+ this.offsetInMilliseconds = offsetInMilliseconds;
+ this.playerActivity = playerActivity;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/BaseDeviceModule.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework;
+
+import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException;
+import com.baidu.duer.dcs.framework.message.ClientContext;
+import com.baidu.duer.dcs.framework.message.Directive;
+
+/**
+ * 定义deviceModule端状态和处理指令的接口
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public abstract class BaseDeviceModule {
+ private final String nameSpace;
+ protected final IMessageSender messageSender;
+
+ public BaseDeviceModule(String nameSpace) {
+ this(nameSpace, null);
+ }
+
+ public BaseDeviceModule(String nameSpace, IMessageSender messageSender) {
+ this.nameSpace = nameSpace;
+ this.messageSender = messageSender;
+ }
+
+ /**
+ * 端状态:服务端在处理某些事件时,需要了解在请求当时设备端各模块所处的状态。比如端上是否正在播放音乐,
+ * 是否有闹钟在响,是否正在播报等等
+ *
+ * @return 端状态
+ */
+ public abstract ClientContext clientContext();
+
+ /**
+ * 处理服务端下发的指令
+ *
+ * @param directive
+ * @throws HandleDirectiveException
+ */
+ public abstract void handleDirective(Directive directive) throws HandleDirectiveException;
+
+ public abstract void release();
+
+ public String getNameSpace() {
+ return nameSpace;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/BaseMultiChannelMediaPlayer.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,464 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework;
+
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+import com.baidu.duer.dcs.systeminterface.IPlatformFactory;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * 1.用途:控制各个DeviceModule的播放策略-基类,主要控制的是{@link com.baidu.duer.dcs.devicemodule.alerts.AlertsDeviceModule}
+ * and {@link com.baidu.duer.dcs.devicemodule.voiceoutput.VoiceOutputDeviceModule}
+ * and {@link com.baidu.duer.dcs.devicemodule.audioplayer.AudioPlayerDeviceModule}
+ * <p>
+ * 2.如果你需要实现自己的策略需要复写handlePlay方法,该sample中提供了一种暂停策略,即
+ * {@link com.baidu.duer.dcs.framework.PauseStrategyMultiChannelMediaPlayer}
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/31.
+ */
+public abstract class BaseMultiChannelMediaPlayer {
+ // 注册的mediaPlayer
+ protected Map<String, ChannelMediaPlayerInfo> mediaPlayers = new ConcurrentHashMap<>();
+ private IPlatformFactory factory;
+
+ public BaseMultiChannelMediaPlayer(IPlatformFactory factory) {
+ this.factory = factory;
+ }
+
+ /**
+ * 添加一个频道并创建一个mediaPlayer
+ *
+ * @param channelName 频道的名字
+ * @param priority 频道的优先级
+ * @return IMediaPlayer 用于处理端能力的播放
+ */
+ public IMediaPlayer addNewChannel(String channelName, int priority) {
+ IMediaPlayer mediaPlayer = factory.createMediaPlayer();
+
+ ChannelMediaPlayerInfo info = new ChannelMediaPlayerInfo();
+ info.channelName = channelName;
+ info.priority = priority;
+ info.mediaPlayer = mediaPlayer;
+ mediaPlayers.put(channelName, info);
+
+ return new ChannelMediaPlayer(info);
+ }
+
+ /**
+ * 处理对话频道(speak), 闹钟/提醒频道(alert),音乐频道(audio)的播放策略,
+ * 比如: 当播放一个低优先级的指令内容时,来了一个高优先级的播放指令是否需要暂停/降低 低优先级频道对应的mediaPlayer
+ *
+ * @param channelName 频道的名字(即通过addNewChannel方法指定的)
+ * @param mediaResource 媒体资源
+ */
+ protected abstract void handlePlay(String channelName, IMediaPlayer.MediaResource mediaResource);
+
+ protected int getPriorityByChannelName(String channelName) {
+ if (mediaPlayers.containsKey(channelName)) {
+ ChannelMediaPlayerInfo info = mediaPlayers.get(channelName);
+ return info.priority;
+ }
+ return UNKNOWN_PRIORITY;
+ }
+
+ /**
+ * 根据频道的名字获取对应的播放器
+ *
+ * @param channelName channelName 频道的名字
+ * @return IMediaPlayer
+ */
+ protected IMediaPlayer getMediaPlayer(String channelName) {
+ if (channelName != null && channelName.length() > 0) {
+ if (mediaPlayers.containsKey(channelName)) {
+ return mediaPlayers.get(channelName).mediaPlayer;
+ }
+ }
+ return null;
+ }
+
+ private static final String TAG = BaseMultiChannelMediaPlayer.class.getSimpleName();
+ protected static final int UNKNOWN_PRIORITY = -1;
+ // 按优先级保存的需要播放的数据
+ protected Map<Integer, ChannelMediaPlayerInfo> currentPlayMap = new TreeMap<>(
+ new Comparator<Integer>() {
+ public int compare(Integer obj1, Integer obj2) {
+ // 降序排序
+ return obj2 - obj1;
+ }
+ });
+
+ /**
+ * 播放信息
+ */
+ protected static class ChannelMediaPlayerInfo {
+ // 播放信息
+ IMediaPlayer.MediaResource mediaResource;
+ // 频道名字
+ String channelName;
+ // 频道优先级
+ int priority;
+ // 播放器
+ IMediaPlayer mediaPlayer;
+ }
+
+ /**
+ * 获取控制音量,静音等操作的实例
+ *
+ * @return ISpeakerController
+ */
+ public ISpeakerController getSpeakerController() {
+ return new SpeakerControllerImpl();
+ }
+
+ /**
+ * 暂停所有的mediaPlayer播放
+ */
+ private void pauseAll() {
+ // 需要暂停所有的播放,有可能没有requestDialogId的指令正在speaking
+ Iterator<Map.Entry<String, ChannelMediaPlayerInfo>> it = mediaPlayers.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, ChannelMediaPlayerInfo> entry = it.next();
+ ChannelMediaPlayerInfo value = entry.getValue();
+ value.mediaPlayer.pause();
+ }
+ }
+
+ private void stop(String channelName) {
+ IMediaPlayer mediaPlayer = getMediaPlayer(channelName);
+ if (mediaPlayer != null) {
+ mediaPlayer.stop();
+ }
+ }
+
+ /**
+ * 设置所有频道的mediaPlayer的音量
+ *
+ * @param volume 音量 0-1
+ */
+ private void setVolumeAll(float volume) {
+ Iterator<Map.Entry<String, ChannelMediaPlayerInfo>> it = mediaPlayers.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, ChannelMediaPlayerInfo> entry = it.next();
+ ChannelMediaPlayerInfo info = entry.getValue();
+ info.mediaPlayer.setVolume(volume);
+ }
+ }
+
+ /**
+ * 获取最高优先级的音量
+ *
+ * @return float 0-1
+ */
+ private float getVolumeTopPriority() {
+ Iterator<Map.Entry<String, ChannelMediaPlayerInfo>> it = mediaPlayers.entrySet().iterator();
+ if (it.hasNext()) {
+ Map.Entry<String, ChannelMediaPlayerInfo> entry = it.next();
+ ChannelMediaPlayerInfo info = entry.getValue();
+ return info.mediaPlayer.getVolume();
+ }
+ return 0;
+ }
+
+ /**
+ * 设置所有频道的mediaPlayer静音状态
+ *
+ * @param mute 静音状态
+ */
+ private void setMuteAll(boolean mute) {
+ Iterator<Map.Entry<String, ChannelMediaPlayerInfo>> it = mediaPlayers.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<String, ChannelMediaPlayerInfo> entry = it.next();
+ ChannelMediaPlayerInfo info = entry.getValue();
+ info.mediaPlayer.setMute(mute);
+ }
+ }
+
+ /**
+ * 获取最高优先级的mediaPlayer静音状态
+ *
+ * @return true 静音,false 非静音
+ */
+ private boolean getMuteTopPriority() {
+ Iterator<Map.Entry<String, ChannelMediaPlayerInfo>> it = mediaPlayers.entrySet().iterator();
+ if (it.hasNext()) {
+ Map.Entry<String, ChannelMediaPlayerInfo> entry = it.next();
+ ChannelMediaPlayerInfo info = entry.getValue();
+ return info.mediaPlayer.getMute();
+ }
+ return false;
+ }
+
+ protected void findToPlay() {
+ LogUtil.d(TAG, "findToPlay");
+ // 找到最高优先级的重新播放
+ Iterator<Map.Entry<Integer, ChannelMediaPlayerInfo>> it = currentPlayMap.entrySet().iterator();
+ if (!it.hasNext()) {
+ return;
+ }
+ Map.Entry<Integer, ChannelMediaPlayerInfo> entry = it.next();
+ ChannelMediaPlayerInfo info = entry.getValue();
+ LogUtil.d(TAG, "findToPlay-channelName:" + info.channelName);
+ if (info.mediaPlayer.getPlayState() == IMediaPlayer.PlayState.PAUSED) {
+ LogUtil.d(TAG, "findToPlay-value-resume:" + info.priority);
+ info.mediaPlayer.resume();
+ } else {
+ LogUtil.d(TAG, "findToPlay-PlayState:" + info.mediaPlayer.getPlayState());
+ // 不是处于正在播放或者准备播放中或者准备完成,开始播放
+ if (info.mediaPlayer.getPlayState() != IMediaPlayer.PlayState.PLAYING
+ && info.mediaPlayer.getPlayState() != IMediaPlayer.PlayState.PREPARING
+ && info.mediaPlayer.getPlayState() != IMediaPlayer.PlayState.PREPARED) {
+ LogUtil.d(TAG, "findToPlay-value-play:" + info.priority);
+ info.mediaPlayer.play(info.mediaResource);
+ } else {
+ LogUtil.d(TAG, "findToPlay-value-isPlaying-false:" + info.priority);
+ }
+ }
+ }
+
+ private final class ListenerProxy extends IMediaPlayer.SimpleMediaPlayerListener {
+ private String channelName;
+
+ ListenerProxy(String channelName) {
+ this.channelName = channelName;
+ }
+
+ @Override
+ public void onStopped() {
+ super.onStopped();
+ // stop 后就删除不需要播放了
+ int priority = getPriorityByChannelName(channelName);
+ LogUtil.d(TAG, "ListenerProxy onStopped del:" + channelName);
+ if (priority != UNKNOWN_PRIORITY) {
+ currentPlayMap.remove(priority);
+ }
+ LogUtil.d(TAG, "ListenerProxy onStopped after del :" + currentPlayMap.size());
+ }
+
+ @Override
+ public void onCompletion() {
+ super.onCompletion();
+ LogUtil.d(TAG, "ListenerProxy onCompletion,channelName:" + channelName);
+ // 删除当前的
+ int priority = BaseMultiChannelMediaPlayer.this.getPriorityByChannelName(channelName);
+ if (priority != UNKNOWN_PRIORITY) {
+ currentPlayMap.remove(priority);
+ }
+ }
+ }
+
+ /**
+ * 带有优先级信息的IMediaPlayer
+ */
+ private final class ChannelMediaPlayer implements IMediaPlayer {
+ private ChannelMediaPlayerInfo mediaPlayerInfo;
+ private String channelName;
+ private IMediaPlayer mediaPlayer;
+
+ ChannelMediaPlayer(ChannelMediaPlayerInfo info) {
+ this.mediaPlayerInfo = info;
+ this.channelName = mediaPlayerInfo.channelName;
+ this.mediaPlayer = mediaPlayerInfo.mediaPlayer;
+ }
+
+ @Override
+ public void play(MediaResource mediaResource) {
+ LogUtil.d(TAG, "ChannelMediaPlayer-play,will handlePlay");
+ BaseMultiChannelMediaPlayer.this.handlePlay(channelName, mediaResource);
+ }
+
+ @Override
+ public void pause() {
+ mediaPlayer.pause();
+ }
+
+ @Override
+ public void stop() {
+ LogUtil.d(TAG, "ChannelMediaPlayer-stop-channelName:" + channelName);
+ BaseMultiChannelMediaPlayer.this.handleStop(channelName);
+ }
+
+ @Override
+ public void resume() {
+ mediaPlayer.resume();
+ }
+
+ @Override
+ public void seekTo(int milliseconds) {
+ mediaPlayer.seekTo(milliseconds);
+ }
+
+ @Override
+ public void release() {
+ mediaPlayer.release();
+ }
+
+ @Override
+ public PlayState getPlayState() {
+ return mediaPlayer.getPlayState();
+ }
+
+ @Override
+ public void setVolume(float volume) {
+ mediaPlayer.setVolume(volume);
+ }
+
+ @Override
+ public float getVolume() {
+ return mediaPlayer.getVolume();
+ }
+
+ @Override
+ public void setMute(boolean mute) {
+ mediaPlayer.setMute(mute);
+ }
+
+ @Override
+ public boolean getMute() {
+ return mediaPlayer.getMute();
+ }
+
+ @Override
+ public long getCurrentPosition() {
+ return mediaPlayer.getCurrentPosition();
+ }
+
+ @Override
+ public long getDuration() {
+ return mediaPlayer.getDuration();
+ }
+
+ @Override
+ public float getBufferPercentage() {
+ return mediaPlayer.getBufferPercentage();
+ }
+
+ @Override
+ public void addMediaPlayerListener(IMediaPlayerListener listener) {
+ // 注意add的顺序
+ // 先1后2的目的是播放完要先从等待播放map中删除对应改成播放完的那一条。
+ // 1.先add wrappedListener
+ IMediaPlayerListener wrappedListener =
+ new ListenerProxy(channelName);
+ mediaPlayer.addMediaPlayerListener(wrappedListener);
+
+ // 2.再addDeviceModule通知到DeviceModule
+ mediaPlayer.addMediaPlayerListener(listener);
+ }
+
+ @Override
+ public void removeMediaPlayerListener(IMediaPlayerListener listener) {
+ mediaPlayer.removeMediaPlayerListener(listener);
+ }
+
+ @Override
+ public void setActive(boolean isActive) {
+ LogUtil.d(TAG, "ChannelMediaPlayer-setActive-isActive:" + isActive);
+ mediaPlayer.setActive(isActive);
+ // 不是处于活跃频道
+ if (!isActive && mediaPlayer.getPlayState() != IMediaPlayer.PlayState.STOPPED) {
+ BaseMultiChannelMediaPlayer.this.handleActive();
+ }
+ }
+
+ @Override
+ public boolean isActive() {
+ return mediaPlayer.isActive();
+ }
+ }
+
+ /**
+ * 处理停止播放
+ */
+ private void handleStop(String channelName) {
+ stop(channelName);
+ pauseAll();
+ }
+
+ /**
+ * 设置对话通道不活跃后的处理逻辑
+ */
+ private void handleActive() {
+ // 找到最高优先级的开始播放
+ findToPlay();
+ }
+
+ /**
+ * 控制接口
+ */
+ public interface ISpeakerController {
+ /**
+ * 设置音量(0-1)
+ *
+ * @param volume 音量(0-1)
+ */
+ void setVolume(float volume);
+
+ /**
+ * 获取当前最高通道的音量
+ *
+ * @return 音量(0-1)
+ */
+ float getVolume();
+
+ /**
+ * 设置是否静音
+ *
+ * @param mute 是否静音
+ */
+ void setMute(boolean mute);
+
+ /**
+ * 获取当前最高通道的静音状态
+ *
+ * @return 静音状态,true 是静音
+ */
+ boolean getMute();
+ }
+
+ /**
+ * 给speak-controller 用的,控制一些音量等操作
+ */
+ private final class SpeakerControllerImpl implements ISpeakerController {
+
+ @Override
+ public void setVolume(float volume) {
+ BaseMultiChannelMediaPlayer.this.setVolumeAll(volume);
+ findToPlay();
+ }
+
+ @Override
+ public float getVolume() {
+ return BaseMultiChannelMediaPlayer.this.getVolumeTopPriority();
+ }
+
+ @Override
+ public void setMute(boolean mute) {
+ BaseMultiChannelMediaPlayer.this.setMuteAll(mute);
+ findToPlay();
+ }
+
+ @Override
+ public boolean getMute() {
+ return BaseMultiChannelMediaPlayer.this.getMuteTopPriority();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/DcsClient.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework;
+
+import com.baidu.duer.dcs.framework.dispatcher.AudioData;
+import com.baidu.duer.dcs.framework.dispatcher.MultipartParser;
+import com.baidu.duer.dcs.framework.heartbeat.HeartBeat;
+import com.baidu.duer.dcs.framework.message.DcsRequestBody;
+import com.baidu.duer.dcs.framework.message.DcsResponseBody;
+import com.baidu.duer.dcs.framework.message.DcsStreamRequestBody;
+import com.baidu.duer.dcs.http.HttpConfig;
+import com.baidu.duer.dcs.http.HttpRequestInterface;
+import com.baidu.duer.dcs.http.OkHttpRequestImpl;
+import com.baidu.duer.dcs.http.callback.ResponseCallback;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.io.IOException;
+
+import okhttp3.Call;
+import okhttp3.Response;
+
+/**
+ * 和服务器端保持长连接、发送events和接收directives和维持心跳
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class DcsClient {
+ public static final String TAG = DcsClient.class.getSimpleName();
+ private final DcsResponseDispatcher dcsResponseDispatcher;
+ private final HttpRequestInterface httpRequestImp;
+ private final HeartBeat heartBeat;
+ private IDcsClientListener dcsClientListener;
+
+ public DcsClient(DcsResponseDispatcher dcsResponseDispatcher, IDcsClientListener dcsClientListener) {
+ this.dcsResponseDispatcher = dcsResponseDispatcher;
+ this.dcsClientListener = dcsClientListener;
+ httpRequestImp = new OkHttpRequestImpl();
+ heartBeat = new HeartBeat(httpRequestImp);
+ heartBeat.setHeartbeatListener(new HeartBeat.IHeartbeatListener() {
+ @Override
+ public void onStartConnect() {
+ startConnect();
+ }
+ });
+ }
+
+ public void release() {
+ heartBeat.release();
+ httpRequestImp.cancelRequest(HttpConfig.HTTP_DIRECTIVES_TAG);
+ httpRequestImp.cancelRequest(HttpConfig.HTTP_EVENT_TAG);
+ }
+
+ /**
+ * 建立连接
+ */
+ public void startConnect() {
+ httpRequestImp.cancelRequest(HttpConfig.HTTP_DIRECTIVES_TAG);
+ getDirectives(new IResponseListener() {
+ @Override
+ public void onSucceed(int statusCode) {
+ LogUtil.d(TAG, "getDirectives onSucceed");
+ fireOnConnected();
+ heartBeat.startNormalPing();
+ }
+
+ @Override
+ public void onFailed(String errorMessage) {
+ LogUtil.d(TAG, "getDirectives onFailed");
+ fireOnUnconnected();
+ heartBeat.startExceptionalPing();
+ }
+ });
+ }
+
+ /**
+ * 发送带流式请求
+ *
+ * @param requestBody 消息体
+ * @param streamRequestBody stream式消息体
+ * @param listener 回调
+ */
+ public void sendRequest(DcsRequestBody requestBody,
+ DcsStreamRequestBody streamRequestBody, final IResponseListener listener) {
+ httpRequestImp.doPostEventMultipartAsync(requestBody,
+ streamRequestBody, getResponseCallback(dcsResponseDispatcher, new IResponseListener() {
+ @Override
+ public void onSucceed(int statusCode) {
+ if (listener != null) {
+ listener.onSucceed(statusCode);
+ }
+ }
+
+ @Override
+ public void onFailed(String errorMessage) {
+ if (listener != null) {
+ listener.onFailed(errorMessage);
+ }
+
+ heartBeat.startImmediatePing();
+ }
+ }));
+ }
+
+ /**
+ * 发送普通请求
+ *
+ * @param requestBody 消息体
+ * @param listener 回调
+ */
+ public void sendRequest(DcsRequestBody requestBody, IResponseListener listener) {
+ httpRequestImp.doPostEventStringAsync(requestBody,
+ getResponseCallback(dcsResponseDispatcher, listener));
+ }
+
+ private void getDirectives(IResponseListener listener) {
+ httpRequestImp.cancelRequest(HttpConfig.HTTP_DIRECTIVES_TAG);
+ httpRequestImp.doGetDirectivesAsync(null,
+ getResponseCallback(dcsResponseDispatcher, listener));
+ }
+
+ private void fireOnConnected() {
+ if (dcsClientListener != null) {
+ dcsClientListener.onConnected();
+ }
+ }
+
+ private void fireOnUnconnected() {
+ if (dcsClientListener != null) {
+ dcsClientListener.onUnconnected();
+ }
+ }
+
+ private ResponseCallback getResponseCallback(final DcsResponseDispatcher dcsResponseDispatcher,
+ final IResponseListener responseListener) {
+ ResponseCallback responseCallback = new ResponseCallback() {
+ @Override
+ public void onError(Call call, Exception e, int id) {
+ LogUtil.d(TAG, "onError,", e);
+ if (responseListener != null) {
+ responseListener.onFailed(e.getMessage());
+ }
+ }
+
+ @Override
+ public void onResponse(Response response, int id) {
+ super.onResponse(response, id);
+ LogUtil.d(TAG, "onResponse OK ," + response.request().url());
+ LogUtil.d(TAG, "onResponse code ," + response.code());
+ if (responseListener != null) {
+ responseListener.onSucceed(response.code());
+ }
+ }
+
+ @Override
+ public Response parseNetworkResponse(Response response, int id) throws Exception {
+ int statusCode = response.code();
+ if (statusCode == 200) {
+ MultipartParser multipartParser = new MultipartParser(
+ new MultipartParser.IMultipartParserListener() {
+ @Override
+ public void onResponseBody(DcsResponseBody responseBody) {
+ dcsResponseDispatcher.onResponseBody(responseBody);
+ }
+
+ @Override
+ public void onAudioData(AudioData audioData) {
+ dcsResponseDispatcher.onAudioData(audioData);
+ }
+
+ @Override
+ public void onParseFailed(String unParseMessage) {
+ dcsResponseDispatcher.onParseFailed(unParseMessage);
+ }
+ });
+
+ try {
+ multipartParser.parseResponse(response);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ return response;
+ }
+ };
+
+ return responseCallback;
+ }
+
+ public interface IDcsClientListener {
+ void onConnected();
+
+ void onUnconnected();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/DcsFramework.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework;
+
+import com.baidu.duer.dcs.devicemodule.system.HandleDirectiveException;
+import com.baidu.duer.dcs.devicemodule.system.SystemDeviceModule;
+import com.baidu.duer.dcs.framework.DcsResponseDispatcher.IDcsResponseHandler;
+import com.baidu.duer.dcs.framework.message.ClientContext;
+import com.baidu.duer.dcs.framework.message.DcsRequestBody;
+import com.baidu.duer.dcs.framework.message.DcsResponseBody;
+import com.baidu.duer.dcs.framework.message.DcsStreamRequestBody;
+import com.baidu.duer.dcs.framework.message.Directive;
+import com.baidu.duer.dcs.framework.message.Event;
+import com.baidu.duer.dcs.systeminterface.IPlatformFactory;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * dcs业务处理框架,用于分发指令(directives)、发送事件(events)和创建deviceModule等
+ * <p>
+ * Created by shenguanghao、wuruisheng on 2017/5/31.
+ */
+public class DcsFramework {
+ private static final String TAG = DcsFramework.class.getSimpleName();
+ // 管理平台相关的对象
+ private final IPlatformFactory platformFactory;
+ // 管理deviceModules
+ private final HashMap<String, BaseDeviceModule> dispatchDeviceModules;
+ // 创建会话Id
+ private final DialogRequestIdHandler dialogRequestIdHandler;
+ // 基于通道活跃状态和优先级进行mediaPlayer调度
+ private final BaseMultiChannelMediaPlayer multiChannelMediaPlayer;
+ // 创建deviceModule工厂
+ private DeviceModuleFactory deviceModuleFactory;
+ // 和服务器端保持长连接、发送events和接收directives和维持心跳
+ private DcsClient dcsClient;
+ // 用于DeviceModules发送events
+ private IMessageSender messageSender;
+ // 服务器端返回response调度中心
+ private DcsResponseDispatcher dcsResponseDispatcher;
+
+ public DcsFramework(IPlatformFactory platformFactory) {
+ this.platformFactory = platformFactory;
+ dispatchDeviceModules = new HashMap<>();
+ dialogRequestIdHandler = new DialogRequestIdHandler();
+ multiChannelMediaPlayer = new PauseStrategyMultiChannelMediaPlayer(platformFactory);
+
+ createMessageSender();
+ createDcsClient();
+ createDeviceModuleFactory();
+ }
+
+ public void release() {
+ for (BaseDeviceModule deviceModule : dispatchDeviceModules.values()) {
+ deviceModule.release();
+ }
+ dcsClient.release();
+ dcsResponseDispatcher.release();
+ }
+
+ public DeviceModuleFactory getDeviceModuleFactory() {
+ return deviceModuleFactory;
+ }
+
+ private ArrayList<ClientContext> clientContexts() {
+ ArrayList<ClientContext> clientContexts = new ArrayList<>();
+ for (BaseDeviceModule deviceModule : dispatchDeviceModules.values()) {
+ ClientContext clientContext = deviceModule.clientContext();
+ if (clientContext != null) {
+ clientContexts.add(clientContext);
+ }
+ }
+
+ return clientContexts;
+ }
+
+ private void handleDirective(Directive directive) {
+ String namespace = directive.header.getNamespace();
+ try {
+ BaseDeviceModule deviceModule = dispatchDeviceModules.get(namespace);
+ if (deviceModule != null) {
+ deviceModule.handleDirective(directive);
+ } else {
+ String message = "No device to handle the directive";
+ throw new HandleDirectiveException(
+ HandleDirectiveException.ExceptionType.UNSUPPORTED_OPERATION, message);
+ }
+ } catch (HandleDirectiveException exception) {
+ getSystemDeviceModule().sendExceptionEncounteredEvent(directive.rawMessage,
+ exception.getExceptionType(), exception.getMessage());
+ } catch (Exception exception) {
+ getSystemDeviceModule().sendExceptionEncounteredEvent(directive.rawMessage,
+ HandleDirectiveException.ExceptionType.INTERNAL_ERROR,
+ exception.getMessage()
+ );
+ }
+ }
+
+ private void createDcsClient() {
+ IDcsResponseHandler responseHandler = new IDcsResponseHandler() {
+ @Override
+ public void onResponse(final DcsResponseBody responseBody) {
+ platformFactory.getMainHandler().post(new Runnable() {
+ @Override
+ public void run() {
+ LogUtil.d(TAG, "DcsResponseBodyEnqueue-handleDirective-MSG:"
+ + responseBody.getDirective().rawMessage);
+ handleDirective(responseBody.getDirective());
+ }
+ });
+ }
+
+ @Override
+ public void onParseFailed(String unParsedMessage) {
+ LogUtil.d(TAG, "DcsResponseBodyEnqueue-handleDirective-onParseFailed");
+ String message = "parse failed";
+ getSystemDeviceModule().sendExceptionEncounteredEvent(unParsedMessage,
+ HandleDirectiveException.ExceptionType.UNEXPECTED_INFORMATION_RECEIVED,
+ message);
+ }
+ };
+
+ dcsResponseDispatcher = new DcsResponseDispatcher(dialogRequestIdHandler, responseHandler);
+ dcsClient = new DcsClient(dcsResponseDispatcher, new DcsClient.IDcsClientListener() {
+ @Override
+ public void onConnected() {
+ LogUtil.d(TAG, "onConnected");
+ getSystemDeviceModule().sendSynchronizeStateEvent();
+ }
+
+ @Override
+ public void onUnconnected() {
+ LogUtil.d(TAG, "onUnconnected");
+ }
+ });
+ dcsClient.startConnect();
+ }
+
+ private void createMessageSender() {
+ messageSender = new IMessageSender() {
+ @Override
+ public void sendEvent(Event event, DcsStreamRequestBody streamRequestBody,
+ IResponseListener responseListener) {
+ DcsRequestBody requestBody = new DcsRequestBody(event);
+ requestBody.setClientContext(clientContexts());
+ dcsClient.sendRequest(requestBody, streamRequestBody, responseListener);
+ }
+
+ @Override
+ public void sendEvent(Event event, IResponseListener responseListener) {
+ sendEventRequest(event, null, responseListener);
+ }
+
+ @Override
+ public void sendEvent(Event event) {
+ sendEventRequest(event, null, null);
+ }
+
+ @Override
+ public void sentEventWithClientContext(Event event, IResponseListener responseListener) {
+ sendEventRequest(event, clientContexts(), responseListener);
+ }
+ };
+ }
+
+ private void sendEventRequest(Event event,
+ ArrayList<ClientContext> clientContexts,
+ IResponseListener responseListener) {
+ DcsRequestBody dcsRequestBody = new DcsRequestBody(event);
+ dcsRequestBody.setClientContext(clientContexts);
+ dcsClient.sendRequest(dcsRequestBody, responseListener);
+ }
+
+ private void createDeviceModuleFactory() {
+ deviceModuleFactory = new DeviceModuleFactory(new DeviceModuleFactory.IDeviceModuleHandler() {
+ @Override
+ public IPlatformFactory getPlatformFactory() {
+ return platformFactory;
+ }
+
+ @Override
+ public DialogRequestIdHandler getDialogRequestIdHandler() {
+ return dialogRequestIdHandler;
+ }
+
+ @Override
+ public IMessageSender getMessageSender() {
+ return messageSender;
+ }
+
+ @Override
+ public BaseMultiChannelMediaPlayer getMultiChannelMediaPlayer() {
+ return multiChannelMediaPlayer;
+ }
+
+ @Override
+ public void addDeviceModule(BaseDeviceModule deviceModule) {
+ DcsFramework.this.addDeviceModule(deviceModule);
+ }
+
+ @Override
+ public DcsResponseDispatcher getResponseDispatcher() {
+ return dcsResponseDispatcher;
+ }
+ });
+ }
+
+ private void addDeviceModule(BaseDeviceModule deviceModule) {
+ dispatchDeviceModules.put(deviceModule.getNameSpace(), deviceModule);
+ }
+
+ private SystemDeviceModule getSystemDeviceModule() {
+ return deviceModuleFactory.getSystemDeviceModule();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/DcsResponseDispatcher.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework;
+
+import com.baidu.duer.dcs.framework.dispatcher.AudioData;
+import com.baidu.duer.dcs.framework.dispatcher.DcsResponseBodyEnqueue;
+import com.baidu.duer.dcs.framework.dispatcher.WithDialogIdBlockThread;
+import com.baidu.duer.dcs.framework.dispatcher.WithoutDialogIdBlockThread;
+import com.baidu.duer.dcs.framework.message.DcsResponseBody;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingDeque;
+
+/**
+ * response调度中心,带有dialogRequestId directives按照顺序执行,对于speak指令播报完才执行下一个指令;
+ * 设备端收到不带dialogRequestId的directives立即执行
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class DcsResponseDispatcher {
+ private final WithDialogIdBlockThread withDialogIdBlockThread;
+ private final WithoutDialogIdBlockThread withoutDialogIdBlockThread;
+ private final BlockingQueue<DcsResponseBody> dependentQueue;
+ private final BlockingQueue<DcsResponseBody> independentQueue;
+ private final DcsResponseBodyEnqueue dcsResponseBodyEnqueue;
+ private final IDcsResponseHandler responseHandler;
+
+ public DcsResponseDispatcher(final DialogRequestIdHandler dialogRequestIdHandler,
+ final IDcsResponseHandler responseHandler) {
+ this.responseHandler = responseHandler;
+ dependentQueue = new LinkedBlockingDeque<>();
+ independentQueue = new LinkedBlockingDeque<>();
+ dcsResponseBodyEnqueue = new DcsResponseBodyEnqueue(dialogRequestIdHandler, dependentQueue,
+ independentQueue);
+
+ withDialogIdBlockThread = new WithDialogIdBlockThread(dependentQueue, responseHandler,
+ "withDialogIdBlockThread");
+ withoutDialogIdBlockThread = new WithoutDialogIdBlockThread(independentQueue, responseHandler,
+ "withoutDialogIdBlockThread");
+ withDialogIdBlockThread.start();
+ withoutDialogIdBlockThread.start();
+ }
+
+ public void interruptDispatch() {
+ // 先清空队列,比如播放一首歌:speak+play指令组合的方式,在speak播报过程中进行打断,play就不需要执行了
+ withDialogIdBlockThread.clear();
+ // 让其处于等待新的指令处理
+ unBlockDependentQueue();
+ }
+
+ public void blockDependentQueue() {
+ withDialogIdBlockThread.block();
+ }
+
+ public void unBlockDependentQueue() {
+ withDialogIdBlockThread.unblock();
+ }
+
+ public void onResponseBody(DcsResponseBody responseBody) {
+ dcsResponseBodyEnqueue.handleResponseBody(responseBody);
+ }
+
+ public void onAudioData(AudioData audioData) {
+ dcsResponseBodyEnqueue.handleAudioData(audioData);
+ }
+
+ public void onParseFailed(String unParseMessage) {
+ if (responseHandler != null) {
+ responseHandler.onParseFailed(unParseMessage);
+ }
+ }
+
+ public void release() {
+ withDialogIdBlockThread.stopThread();
+ withoutDialogIdBlockThread.stopThread();
+ }
+
+ public interface IDcsResponseHandler {
+ void onResponse(DcsResponseBody responseBody);
+
+ void onParseFailed(String unParseMessage);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/DeviceModuleFactory.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework;
+
+import com.baidu.duer.dcs.devicemodule.alerts.AlertsDeviceModule;
+import com.baidu.duer.dcs.devicemodule.audioplayer.AudioPlayerDeviceModule;
+import com.baidu.duer.dcs.devicemodule.playbackcontroller.PlaybackControllerDeviceModule;
+import com.baidu.duer.dcs.devicemodule.screen.ScreenDeviceModule;
+import com.baidu.duer.dcs.devicemodule.speakcontroller.SpeakerControllerDeviceModule;
+import com.baidu.duer.dcs.devicemodule.system.SystemDeviceModule;
+import com.baidu.duer.dcs.devicemodule.system.message.SetEndPointPayload;
+import com.baidu.duer.dcs.devicemodule.system.message.ThrowExceptionPayload;
+import com.baidu.duer.dcs.devicemodule.voiceinput.VoiceInputDeviceModule;
+import com.baidu.duer.dcs.devicemodule.voiceoutput.VoiceOutputDeviceModule;
+import com.baidu.duer.dcs.http.HttpConfig;
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+import com.baidu.duer.dcs.systeminterface.IPlatformFactory;
+import com.baidu.duer.dcs.systeminterface.IPlaybackController;
+import com.baidu.duer.dcs.systeminterface.IWebView;
+import com.baidu.duer.dcs.util.LogUtil;
+
+/**
+ * 创建语音输入、语音输出、扬声器、音频播放器、播放控制、闹钟、屏幕显示和系统等deviceModule
+ * <p>
+ * Created by wuruisheng on 2017/6/15.
+ */
+public class DeviceModuleFactory {
+ private static final String TAG = DeviceModuleFactory.class.getSimpleName();
+ private final IDeviceModuleHandler deviceModuleHandler;
+ private final IMediaPlayer dialogMediaPlayer;
+
+ private VoiceInputDeviceModule voiceInputDeviceModule;
+ private VoiceOutputDeviceModule voiceOutputDeviceModule;
+ private SpeakerControllerDeviceModule speakerControllerDeviceModule;
+ private AudioPlayerDeviceModule audioPlayerDeviceModule;
+ private AlertsDeviceModule alertsDeviceModule;
+ private SystemDeviceModule systemDeviceModule;
+ private PlaybackControllerDeviceModule playbackControllerDeviceModule;
+ private ScreenDeviceModule screenDeviceModule;
+
+ // 数字越大,优先级越高,播放优先级
+ private enum MediaChannel {
+ SPEAK("dialog", 3),
+ ALERT("alert", 2),
+ AUDIO("audio", 1);
+
+ private String channelName;
+ private int priority;
+
+ MediaChannel(String channelName, int priority) {
+ this.channelName = channelName;
+ this.priority = priority;
+ }
+ }
+
+ public DeviceModuleFactory(final IDeviceModuleHandler deviceModuleHandler) {
+ this.deviceModuleHandler = deviceModuleHandler;
+ dialogMediaPlayer = deviceModuleHandler.getMultiChannelMediaPlayer()
+ .addNewChannel(MediaChannel.SPEAK.channelName, MediaChannel.SPEAK.priority);
+ }
+
+
+ public void createVoiceInputDeviceModule() {
+ /*
+ * 传入VoiceOutput的MediaPlayer,因为根据dcs协议的规范
+ * 对话通道:
+ * 对应语音输入(Voice Input)和语音输出(Voice Output)端能力;
+ * 用户在语音请求时,或者设备在执行Speak指令进行播报时,对话通道进入活跃状态
+ */
+ voiceInputDeviceModule = new VoiceInputDeviceModule(
+ dialogMediaPlayer, deviceModuleHandler.getMessageSender(),
+ deviceModuleHandler.getPlatformFactory().getVoiceInput(),
+ deviceModuleHandler.getDialogRequestIdHandler(),
+ deviceModuleHandler.getResponseDispatcher());
+ deviceModuleHandler.addDeviceModule(voiceInputDeviceModule);
+ }
+
+ public VoiceInputDeviceModule getVoiceInputDeviceModule() {
+ return voiceInputDeviceModule;
+ }
+
+ public void createVoiceOutputDeviceModule() {
+ voiceOutputDeviceModule = new VoiceOutputDeviceModule(dialogMediaPlayer,
+ deviceModuleHandler.getMessageSender());
+ voiceOutputDeviceModule.addVoiceOutputListener(new VoiceOutputDeviceModule.IVoiceOutputListener() {
+ @Override
+ public void onVoiceOutputStarted() {
+ LogUtil.d(TAG, "DcsResponseBodyEnqueue-onVoiceOutputStarted ok ");
+ deviceModuleHandler.getResponseDispatcher().blockDependentQueue();
+ }
+
+ @Override
+ public void onVoiceOutputFinished() {
+ LogUtil.d(TAG, "DcsResponseBodyEnqueue-onVoiceOutputFinished ok ");
+ deviceModuleHandler.getResponseDispatcher().unBlockDependentQueue();
+ }
+ });
+
+ deviceModuleHandler.addDeviceModule(voiceOutputDeviceModule);
+ }
+
+ public void createSpeakControllerDeviceModule() {
+ BaseMultiChannelMediaPlayer.ISpeakerController speakerController =
+ deviceModuleHandler.getMultiChannelMediaPlayer().getSpeakerController();
+ speakerControllerDeviceModule =
+ new SpeakerControllerDeviceModule(speakerController,
+ deviceModuleHandler.getMessageSender());
+ deviceModuleHandler.addDeviceModule(speakerControllerDeviceModule);
+ }
+
+ public void createAudioPlayerDeviceModule() {
+ IMediaPlayer mediaPlayer = deviceModuleHandler.getMultiChannelMediaPlayer()
+ .addNewChannel(MediaChannel.AUDIO.channelName,
+ MediaChannel.AUDIO.priority);
+ audioPlayerDeviceModule = new AudioPlayerDeviceModule(mediaPlayer,
+ deviceModuleHandler.getMessageSender());
+ deviceModuleHandler.addDeviceModule(audioPlayerDeviceModule);
+ }
+
+ public AudioPlayerDeviceModule getAudioPlayerDeviceModule() {
+ return audioPlayerDeviceModule;
+ }
+
+ public void createAlertsDeviceModule() {
+ IMediaPlayer mediaPlayer = deviceModuleHandler.getMultiChannelMediaPlayer()
+ .addNewChannel(MediaChannel.ALERT.channelName,
+ MediaChannel.ALERT.priority);
+ alertsDeviceModule = new AlertsDeviceModule(mediaPlayer,
+ deviceModuleHandler.getPlatformFactory().createAlertsDataStore(),
+ deviceModuleHandler.getMessageSender(),
+ deviceModuleHandler.getPlatformFactory().getMainHandler());
+
+ alertsDeviceModule.addAlertListener(new AlertsDeviceModule.IAlertListener() {
+ @Override
+ public void onAlertStarted(String alertToken) {
+ }
+ });
+
+ deviceModuleHandler.addDeviceModule(alertsDeviceModule);
+ }
+
+ public void createSystemDeviceModule() {
+ systemDeviceModule = new SystemDeviceModule(deviceModuleHandler.getMessageSender());
+ systemDeviceModule.addModuleListener(new SystemDeviceModule.IDeviceModuleListener() {
+ @Override
+ public void onSetEndpoint(SetEndPointPayload endPointPayload) {
+ if (null != endPointPayload) {
+ String endpoint = endPointPayload.getEndpoint();
+ if (null != endpoint && endpoint.length() > 0) {
+ HttpConfig.setEndpoint(endpoint);
+ }
+ }
+ }
+
+ @Override
+ public void onThrowException(ThrowExceptionPayload throwExceptionPayload) {
+ LogUtil.v(TAG, throwExceptionPayload.toString());
+ }
+ });
+ deviceModuleHandler.addDeviceModule(systemDeviceModule);
+ }
+
+ public SystemDeviceModule getSystemDeviceModule() {
+ return systemDeviceModule;
+ }
+
+ public SystemDeviceModule.Provider getSystemProvider() {
+ return systemDeviceModule.getProvider();
+ }
+
+ public void createPlaybackControllerDeviceModule() {
+ IPlaybackController playback = deviceModuleHandler.getPlatformFactory().getPlayback();
+ playbackControllerDeviceModule = new PlaybackControllerDeviceModule(playback,
+ deviceModuleHandler.getMessageSender(), alertsDeviceModule);
+ deviceModuleHandler.addDeviceModule(playbackControllerDeviceModule);
+ }
+
+ public void createScreenDeviceModule() {
+ IWebView webView = deviceModuleHandler.getPlatformFactory().getWebView();
+ screenDeviceModule = new ScreenDeviceModule(webView, deviceModuleHandler.getMessageSender());
+ deviceModuleHandler.addDeviceModule(screenDeviceModule);
+ }
+
+ public interface IDeviceModuleHandler {
+ IPlatformFactory getPlatformFactory();
+
+ DialogRequestIdHandler getDialogRequestIdHandler();
+
+ IMessageSender getMessageSender();
+
+ BaseMultiChannelMediaPlayer getMultiChannelMediaPlayer();
+
+ void addDeviceModule(BaseDeviceModule deviceModule);
+
+ DcsResponseDispatcher getResponseDispatcher();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/DialogRequestIdHandler.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework;
+
+import java.util.UUID;
+
+/**
+ * 生成dialogRequestId
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public class DialogRequestIdHandler {
+ private String activeDialogRequestId;
+
+ public DialogRequestIdHandler() {
+ }
+
+ public String createActiveDialogRequestId() {
+ activeDialogRequestId = UUID.randomUUID().toString();
+ return activeDialogRequestId;
+ }
+
+ /**
+ * 判断当前dialogRequestId是否活跃的
+ *
+ * @param dialogRequestId dialogRequestId
+ * @return dialogRequestId与activeDialogRequestId相等则返回true,否则返回false
+ */
+ public Boolean isActiveDialogRequestId(String dialogRequestId) {
+ return activeDialogRequestId != null && activeDialogRequestId.equals(dialogRequestId);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/IMessageSender.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework;
+
+import com.baidu.duer.dcs.framework.message.DcsStreamRequestBody;
+import com.baidu.duer.dcs.framework.message.Event;
+
+/**
+ * 发送event接口
+ * <p>
+ * Created by wuruisheng on 2017/6/15.
+ */
+public interface IMessageSender {
+ /**
+ * 发送event
+ *
+ * @param event
+ */
+ void sendEvent(Event event);
+
+ /**
+ * 发送event
+ *
+ * @param event
+ * @param responseListener 回调
+ */
+ void sendEvent(Event event, IResponseListener responseListener);
+
+ /**
+ * 发送event且带有stream
+ *
+ * @param event event对象
+ * @param streamRequestBody stream对象
+ * @param responseListener 回调
+ */
+ void sendEvent(Event event, DcsStreamRequestBody streamRequestBody, IResponseListener responseListener);
+
+ /**
+ * 发送event带上clientContext
+ *
+ * @param event event对象
+ * @param responseListener 回调
+ */
+ void sentEventWithClientContext(Event event, IResponseListener responseListener);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/IResponseListener.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework;
+
+/**
+ * 网络请求回调
+ * <p>
+ * Created by wuruisheng on 2017/6/17.
+ */
+public interface IResponseListener {
+ /**
+ * 成功回调
+ *
+ * @param statusCode http返回statusCode
+ */
+ void onSucceed(int statusCode);
+
+ /**
+ * 失败回调
+ *
+ * @param errorMessage 出错的异常信息
+ */
+ void onFailed(String errorMessage);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/PauseStrategyMultiChannelMediaPlayer.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework;
+
+import com.baidu.duer.dcs.systeminterface.IMediaPlayer;
+import com.baidu.duer.dcs.systeminterface.IPlatformFactory;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * 暂停模式的播放控制策略
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/6.
+ */
+public class PauseStrategyMultiChannelMediaPlayer extends BaseMultiChannelMediaPlayer {
+ private static final String TAG = BaseMultiChannelMediaPlayer.class.getSimpleName();
+
+ public PauseStrategyMultiChannelMediaPlayer(IPlatformFactory factory) {
+ super(factory);
+ }
+
+ @Override
+ protected void handlePlay(String channelName, IMediaPlayer.MediaResource mediaResource) {
+ int priority = getPriorityByChannelName(channelName);
+ LogUtil.d(TAG, "handlePlay-priority:" + priority);
+ if (priority == UNKNOWN_PRIORITY) {
+ return;
+ }
+ ChannelMediaPlayerInfo info = new ChannelMediaPlayerInfo();
+ info.mediaPlayer = getMediaPlayer(channelName);
+ info.priority = priority;
+ info.channelName = channelName;
+ info.mediaResource = mediaResource;
+ currentPlayMap.put(priority, info);
+
+ // 把比当前优先级低的播放器都暂停
+ Iterator<Map.Entry<Integer, ChannelMediaPlayerInfo>> it = currentPlayMap.entrySet().iterator();
+ while (it.hasNext()) {
+ Map.Entry<Integer, ChannelMediaPlayerInfo> entry = it.next();
+ ChannelMediaPlayerInfo value = entry.getValue();
+ LogUtil.d(TAG, "handlePlay-value:" + value.priority);
+ if (priority > value.priority) {
+ LogUtil.d(TAG, "handlePlay-value-pause:" + value.priority);
+ value.mediaPlayer.pause();
+ }
+ }
+ findToPlay();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/dispatcher/AudioData.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.dispatcher;
+
+/**
+ * 存储音频数据
+ * <p>
+ * Created by wuruisheng on 2017/5/13.
+ */
+public class AudioData {
+ public String contentId;
+ public byte[] partBytes;
+
+ public AudioData(String contentId, byte[] partBytes) {
+ this.contentId = contentId;
+ this.partBytes = partBytes;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/dispatcher/BaseBlockResponseThread.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.dispatcher;
+
+import com.baidu.duer.dcs.framework.DcsResponseDispatcher;
+import com.baidu.duer.dcs.framework.message.DcsResponseBody;
+
+import java.util.concurrent.BlockingQueue;
+
+/**
+ * 单独线程阻塞控制response回调处理
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public abstract class BaseBlockResponseThread extends Thread {
+ private static final String TAG = BaseBlockResponseThread.class.getSimpleName();
+ private BlockingQueue<DcsResponseBody> responseBodyDeque;
+ private DcsResponseDispatcher.IDcsResponseHandler responseHandler;
+ private volatile boolean block;
+ private volatile boolean isStop;
+
+ public BaseBlockResponseThread(BlockingQueue<DcsResponseBody> responseBodyDeque,
+ DcsResponseDispatcher.IDcsResponseHandler responseHandler, String threadName) {
+ this.responseBodyDeque = responseBodyDeque;
+ this.responseHandler = responseHandler;
+ setName(threadName);
+ }
+
+ public synchronized void block() {
+ block = true;
+ }
+
+ public synchronized void unblock() {
+ block = false;
+ notify();
+ }
+
+ public synchronized void clear() {
+ responseBodyDeque.clear();
+ }
+
+ public synchronized void stopThread() {
+ clear();
+ isStop = true;
+ this.interrupt();
+ }
+
+ @Override
+ public void run() {
+ while (!isStop) {
+ try {
+ synchronized (this) {
+ if (block) {
+ wait();
+ }
+ }
+
+ if (responseHandler != null) {
+ DcsResponseBody responseBody = responseBodyDeque.take();
+ responseHandler.onResponse(responseBody);
+
+ if (shouldBlock(responseBody)) {
+ block = true;
+ }
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ abstract boolean shouldBlock(DcsResponseBody responseBody);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/dispatcher/DcsJsonProcessingException.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.dispatcher;
+
+import org.codehaus.jackson.JsonProcessingException;
+
+/**
+ * json序列化成异常对象
+ * <p>
+ * Created by wuruisheng on 2017/6/8.
+ */
+public class DcsJsonProcessingException extends JsonProcessingException {
+ private String unparsedCotent;
+
+ public DcsJsonProcessingException(String message, JsonProcessingException exception, String unparsedCotent) {
+ super(message, exception);
+ this.unparsedCotent = unparsedCotent;
+ }
+
+ public String getUnparsedCotent() {
+ return unparsedCotent;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/dispatcher/DcsResponseBodyEnqueue.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.dispatcher;
+
+import com.baidu.duer.dcs.framework.message.AttachedContentPayload;
+import com.baidu.duer.dcs.framework.message.DcsResponseBody;
+import com.baidu.duer.dcs.framework.DialogRequestIdHandler;
+import com.baidu.duer.dcs.framework.message.DialogRequestIdHeader;
+import com.baidu.duer.dcs.framework.message.Directive;
+import com.baidu.duer.dcs.framework.message.Header;
+import com.baidu.duer.dcs.framework.message.Payload;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Queue;
+
+/**
+ * 带有dialogRequestId response进入dependentQueue队列,否则进入independentQueue
+ * 带有attached的directive需要知道找到对应的二进制数据才放到上述队列中
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class DcsResponseBodyEnqueue {
+ private static final String TAG = DcsResponseBodyEnqueue.class.getSimpleName();
+ private final DialogRequestIdHandler dialogRequestIdHandler;
+ private final Queue<DcsResponseBody> dependentQueue;
+ private final Queue<DcsResponseBody> independentQueue;
+ private final Queue<DcsResponseBody> incompleteResponseQueue;
+ private final Map<String, AudioData> audioDataMap;
+
+ public DcsResponseBodyEnqueue(DialogRequestIdHandler dialogRequestIdHandler,
+ Queue<DcsResponseBody> dependentQueue,
+ Queue<DcsResponseBody> independentQueue) {
+ this.dialogRequestIdHandler = dialogRequestIdHandler;
+ this.dependentQueue = dependentQueue;
+ this.independentQueue = independentQueue;
+ incompleteResponseQueue = new LinkedList<>();
+ audioDataMap = new HashMap<>();
+ }
+
+ public synchronized void handleResponseBody(DcsResponseBody responseBody) {
+ incompleteResponseQueue.add(responseBody);
+ matchAudioDataWithResponseBody();
+ }
+
+ public synchronized void handleAudioData(AudioData audioData) {
+ audioDataMap.put(audioData.contentId, audioData);
+ matchAudioDataWithResponseBody();
+ }
+
+ private void matchAudioDataWithResponseBody() {
+ for (DcsResponseBody responseBody : incompleteResponseQueue) {
+ Directive directive = responseBody.getDirective();
+ if (directive == null) {
+ return;
+ }
+
+ Payload payload = responseBody.getDirective().payload;
+ if (payload instanceof AttachedContentPayload) {
+ AttachedContentPayload attachedContentPayload = (AttachedContentPayload) payload;
+ String contentId = attachedContentPayload.getAttachedContentId();
+ AudioData audioData = audioDataMap.remove(contentId);
+ if (audioData != null) {
+ attachedContentPayload.setAttachedContent(contentId, audioData.partBytes);
+ }
+ }
+ }
+
+ findCompleteResponseBody();
+ }
+
+ private void findCompleteResponseBody() {
+ Iterator<DcsResponseBody> iterator = incompleteResponseQueue.iterator();
+ while (iterator.hasNext()) {
+ DcsResponseBody responseBody = iterator.next();
+ Payload payload = responseBody.getDirective().payload;
+ if (payload instanceof AttachedContentPayload) {
+ AttachedContentPayload attachedContentPayload = (AttachedContentPayload) payload;
+
+ if (!attachedContentPayload.requiresAttachedContent()) {
+ // The front most directive IS complete.
+ enqueueResponseBody(responseBody);
+ iterator.remove();
+ } else {
+ break;
+ }
+ } else {
+ // Immediately enqueue any directive which does not contain audio content
+ enqueueResponseBody(responseBody);
+ iterator.remove();
+ }
+ }
+ }
+
+ private void enqueueResponseBody(DcsResponseBody responseBody) {
+ LogUtil.d(TAG, "DcsResponseBodyEnqueue-RecordThread:" + responseBody.getDirective().rawMessage);
+ Header header = responseBody.getDirective().header;
+ DialogRequestIdHeader dialogRequestIdHeader = (DialogRequestIdHeader) header;
+ if (dialogRequestIdHeader.getDialogRequestId() == null) {
+ LogUtil.d(TAG, "DcsResponseBodyEnqueue-DialogRequestId is null ,add to independentQueue");
+ independentQueue.add(responseBody);
+ } else if (dialogRequestIdHandler.isActiveDialogRequestId(dialogRequestIdHeader.getDialogRequestId())) {
+ LogUtil.d(TAG, "DcsResponseBodyEnqueue-DialogRequestId not null,add to dependentQueue");
+ dependentQueue.add(responseBody);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/dispatcher/MultipartParser.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,174 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.dispatcher;
+
+import com.baidu.duer.dcs.framework.message.DcsResponseBody;
+import com.baidu.duer.dcs.http.HttpConfig;
+
+import org.apache.commons.fileupload.MultipartStream;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+
+import okhttp3.Response;
+
+/**
+ * 把从服务器返回multipart中json对象和二进制解析成directive对象
+ * <p>
+ * Created by wuruisheng on 2017/5/12.
+ */
+public class MultipartParser extends Parser {
+ private static final int BUFFER_SIZE = 512;
+ private final IMultipartParserListener multipartParserListener;
+
+ public MultipartParser(IMultipartParserListener listener) {
+ this.multipartParserListener = listener;
+ }
+
+ public void parseResponse(Response response) throws IOException {
+ String boundary = getBoundary(response);
+ if (boundary != null) {
+ parseStream(response.body().byteStream(), boundary);
+ }
+ }
+
+ private void parseStream(InputStream inputStream, String boundary) throws IOException {
+ MultipartStream multipartStream = new MultipartStream(inputStream, boundary.getBytes(), BUFFER_SIZE, null);
+ parseMultipartStream(multipartStream);
+ }
+
+ private void parseMultipartStream(MultipartStream multipartStream) throws IOException {
+ try {
+ Boolean hasNextPart = multipartStream.skipPreamble();
+ while (hasNextPart) {
+ handlePart(multipartStream);
+ hasNextPart = multipartStream.readBoundary();
+ }
+ } catch (DcsJsonProcessingException exception) {
+ if (multipartParserListener != null) {
+ multipartParserListener.onParseFailed(exception.getUnparsedCotent());
+ }
+ } catch (MultipartStream.MalformedStreamException exception) {
+ // 用于处理 empty part
+ }
+ }
+
+ private void handlePart(MultipartStream multipartStream) throws IOException {
+ Map<String, String> headers = getPartHeaders(multipartStream);
+ if (headers != null) {
+ byte[] partBytes = getPartBytes(multipartStream);
+ Boolean isJsonData = isPartJSON(headers);
+ if (isJsonData) {
+ handleJsonData(partBytes);
+ } else {
+ handleAudio(headers, partBytes);
+ }
+ }
+ }
+
+ private void handleJsonData(byte[] partBytes) throws IOException {
+ final DcsResponseBody responseBody = parse(partBytes, DcsResponseBody.class);
+ if (multipartParserListener != null) {
+ multipartParserListener.onResponseBody(responseBody);
+ }
+ }
+
+ private void handleAudio(Map<String, String> headers, byte[] partBytes) {
+ String contentId = getMultipartContentId(headers);
+ final AudioData audioData = new AudioData(contentId, partBytes);
+ if (multipartParserListener != null) {
+ multipartParserListener.onAudioData(audioData);
+ }
+ }
+
+ private byte[] getPartBytes(MultipartStream multipartStream) throws IOException {
+ ByteArrayOutputStream data = new ByteArrayOutputStream();
+ multipartStream.readBodyData(data);
+ return data.toByteArray();
+ }
+
+ private Map<String, String> getPartHeaders(MultipartStream multipartStream) throws IOException {
+ String headers = multipartStream.readHeaders();
+ BufferedReader reader = new BufferedReader(new StringReader(headers));
+ Map<String, String> headerMap = new HashMap<>();
+ try {
+ for (String line = reader.readLine(); line != null; line = reader.readLine()) {
+ line = line.trim();
+ if (!StringUtils.isBlank(line) && line.contains(":")) {
+ int colon = line.indexOf(":");
+ String headerName = line.substring(0, colon).trim();
+ String headerValue = line.substring(colon + 1).trim();
+ headerMap.put(headerName.toLowerCase(), headerValue);
+ }
+ }
+ } catch (Exception e) {
+ throw e;
+ }
+
+ return headerMap;
+ }
+
+ private String getMultipartHeaderValue(Map<String, String> headers, String searchHeader) {
+ return headers.get(searchHeader.toLowerCase());
+ }
+
+ private String getMultipartContentId(Map<String, String> headers) {
+ String contentId = getMultipartHeaderValue(headers, HttpConfig.HttpHeaders.CONTENT_ID);
+ contentId = contentId.substring(1, contentId.length() - 1);
+ return contentId;
+ }
+
+ private boolean isPartJSON(Map<String, String> headers) {
+ String contentType = getMultipartHeaderValue(headers, HttpConfig.HttpHeaders.CONTENT_TYPE);
+ return StringUtils.contains(contentType, HttpConfig.ContentTypes.JSON);
+ }
+
+ private static String getBoundary(Response response) {
+ String headerValue = response.header(HttpConfig.HttpHeaders.CONTENT_TYPE);
+ String boundary = getHeaderParameter(headerValue, HttpConfig.Parameters.BOUNDARY);
+ return boundary;
+ }
+
+ private static String getHeaderParameter(final String headerValue, final String key) {
+ if ((headerValue == null) || (key == null)) {
+ return null;
+ }
+
+ String[] parts = headerValue.split(";");
+ for (String part : parts) {
+ part = part.trim();
+ if (part.startsWith(key)) {
+ return part.substring(key.length() + 1).replaceAll("(^\")|(\"$)", "").trim();
+ }
+ }
+
+ return null;
+ }
+
+ public interface IMultipartParserListener {
+ void onResponseBody(DcsResponseBody responseBody);
+
+ void onAudioData(AudioData audioData);
+
+ void onParseFailed(String unParseMessage);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/dispatcher/Parser.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.dispatcher;
+
+import com.baidu.duer.dcs.util.ObjectMapperUtil;
+
+import org.codehaus.jackson.JsonProcessingException;
+
+import java.io.IOException;
+
+/**
+ * 字节数据转换成对象
+ * <p>
+ * Created by wuruisheng on 2017/5/12.
+ */
+public class Parser {
+ protected <T> T parse(byte[] bytes, Class<T> clazz) throws IOException {
+ try {
+ return ObjectMapperUtil.instance().getObjectReader().withType(clazz).readValue(bytes);
+ } catch (JsonProcessingException e) {
+ String unparsedContent = new String(bytes, "UTF-8");
+ String message = String.format("failed to parse %1$s", clazz.getSimpleName());
+ throw new DcsJsonProcessingException(message, e, unparsedContent);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/dispatcher/WithDialogIdBlockThread.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.dispatcher;
+
+import com.baidu.duer.dcs.devicemodule.voiceoutput.ApiConstants;
+import com.baidu.duer.dcs.framework.DcsResponseDispatcher;
+import com.baidu.duer.dcs.framework.message.DcsResponseBody;
+
+import java.util.concurrent.BlockingQueue;
+
+/**
+ * 服务器返回的指令header中有dialogRequestId调度线程
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/12.
+ */
+public class WithDialogIdBlockThread extends BaseBlockResponseThread {
+
+ public WithDialogIdBlockThread(BlockingQueue<DcsResponseBody> responseBodyDeque,
+ DcsResponseDispatcher.IDcsResponseHandler responseHandler,
+ String threadName) {
+ super(responseBodyDeque, responseHandler, threadName);
+ }
+
+ @Override
+ boolean shouldBlock(DcsResponseBody responseBody) {
+ // 如果是speak指令就立马阻塞
+ String directiveName = responseBody.getDirective().getName();
+ return directiveName != null && directiveName.length() > 0
+ && directiveName.equals(ApiConstants.Directives.Speak.NAME);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/dispatcher/WithoutDialogIdBlockThread.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.dispatcher;
+
+import com.baidu.duer.dcs.framework.DcsResponseDispatcher;
+import com.baidu.duer.dcs.framework.message.DcsResponseBody;
+
+import java.util.concurrent.BlockingQueue;
+
+/**
+ * 服务器返回的指令header中没有dialogRequestId调度线程
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/12.
+ */
+public class WithoutDialogIdBlockThread extends BaseBlockResponseThread {
+ public WithoutDialogIdBlockThread(BlockingQueue<DcsResponseBody> responseBodyDeque,
+ DcsResponseDispatcher.IDcsResponseHandler responseHandler,
+ String threadName) {
+ super(responseBodyDeque, responseHandler, threadName);
+ }
+
+ @Override
+ boolean shouldBlock(DcsResponseBody responseBody) {
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/heartbeat/HeartBeat.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.heartbeat;
+
+import com.baidu.duer.dcs.http.HttpConfig;
+import com.baidu.duer.dcs.http.HttpRequestInterface;
+import com.baidu.duer.dcs.http.callback.ResponseCallback;
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import okhttp3.Call;
+import okhttp3.Response;
+
+/**
+ * 用于检测Directives 是否正常
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/17.
+ */
+public class HeartBeat {
+ private static final String TAG = HeartBeat.class.getSimpleName();
+ // 设置ping成功后的(ping成功即代表directive请求成功了)请求的时间间隔
+ // 修改成270s原因:国内网关保持一个连接时间一般都是300s
+ private static final long PING_TIME_SUCCEED = 30 * 1000;
+ // 设置ping失败后的(ping失败即代表directive请求失败了)请求的时间间隔
+ private static final long PING_TIME_FAILED = 5 * 1000;
+ private final HttpRequestInterface httpRequest;
+ private Timer timer;
+ private PingTask pingTask;
+ private IHeartbeatListener listener;
+ // 连接状态
+ private ConnectState connectState;
+
+ private enum ConnectState {
+ CONNECTED,
+ UNCONNECTED
+ }
+
+ public HeartBeat(HttpRequestInterface httpRequest) {
+ this.httpRequest = httpRequest;
+ timer = new Timer();
+ }
+
+ /**
+ * 如果Directives连接成功了,调用此方法进行探测
+ */
+ public void startNormalPing() {
+ connectState = ConnectState.CONNECTED;
+ startPing(PING_TIME_SUCCEED, PING_TIME_SUCCEED);
+ }
+
+ /**
+ * 如果Directives连接异常了,调用此方法进行探测
+ */
+ public void startExceptionalPing() {
+ connectState = ConnectState.UNCONNECTED;
+ startPing(PING_TIME_FAILED, PING_TIME_FAILED);
+ }
+
+ /**
+ * 如果Events连接异常了,调用此方法进行探测
+ */
+ public void startImmediatePing() {
+ connectState = ConnectState.UNCONNECTED;
+ startPing(0, PING_TIME_FAILED);
+ }
+
+ private void fireOnConnect() {
+ if (listener != null) {
+ listener.onStartConnect();
+ }
+ }
+
+ private void startPing(long delay, long timeInterval) {
+ if (pingTask != null) {
+ pingTask.cancel();
+ }
+ pingTask = new PingTask();
+ if (timer != null) {
+ timer.schedule(pingTask, delay, timeInterval);
+ }
+ }
+
+ /**
+ * 停止ping探测,释放资源
+ */
+ public void release() {
+ if (pingTask != null) {
+ pingTask.cancel();
+ pingTask = null;
+ }
+
+ timer.cancel();
+ timer = null;
+ httpRequest.cancelRequest(HttpConfig.HTTP_PING_TAG);
+ }
+
+ private void ping() {
+ httpRequest.cancelRequest(HttpConfig.HTTP_PING_TAG);
+ httpRequest.doGetPingAsync(null, new ResponseCallback() {
+ @Override
+ public void onError(Call call, Exception e, int id) {
+ super.onError(call, e, id);
+ LogUtil.d(TAG, "ping onError");
+ connectState = ConnectState.UNCONNECTED;
+ fireOnConnect();
+ }
+
+ @Override
+ public void onResponse(Response response, int id) {
+ super.onResponse(response, id);
+ LogUtil.d(TAG, "ping onResponse, code :" + response.code());
+ if (response.code() == 200 || response.code() == 204) {
+ if (connectState == ConnectState.UNCONNECTED) {
+ fireOnConnect();
+ }
+ } else {
+ connectState = ConnectState.UNCONNECTED;
+ fireOnConnect();
+ }
+ }
+ });
+ }
+
+ public void setHeartbeatListener(IHeartbeatListener listener) {
+ this.listener = listener;
+ }
+
+ /**
+ * ping 回调接口
+ */
+ public interface IHeartbeatListener {
+ /**
+ * 需要建立长连接时回调
+ */
+ void onStartConnect();
+ }
+
+ private final class PingTask extends TimerTask {
+ @Override
+ public void run() {
+ ping();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/AttachedContentPayload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+/**
+ * 语音输出speak指令附加内容
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/1.
+ */
+public interface AttachedContentPayload {
+ boolean requiresAttachedContent();
+ boolean hasAttachedContent();
+ String getAttachedContentId();
+ byte[] getAttachedContent();
+ void setAttachedContent(String contentId, byte[] attachmentContent);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/BaseMessage.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+/**
+ * 带有header和payload的消息体基类
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/1.
+ */
+public class BaseMessage {
+ private Header header;
+ private Payload payload;
+
+ public BaseMessage(Header header, Payload payload) {
+ this.header = header;
+ this.payload = payload;
+ }
+
+ public void setHeader(Header header) {
+ this.header = header;
+ }
+
+ public Header getHeader() {
+ return header;
+ }
+
+ public void setPayload(Payload payload) {
+ this.payload = payload;
+ }
+
+ public Payload getPayload() {
+ return payload;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/ClientContext.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+/**
+ * 端状态:服务端在处理某些事件时,需要了解在请求当时设备端各模块所处的状态。比如端上是否正在播放音乐,
+ * 是否有闹钟在响,是否正在播报等等
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public class ClientContext extends BaseMessage {
+ public ClientContext(Header header, Payload payload) {
+ super(header, payload);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/DcsRequestBody.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+import org.codehaus.jackson.map.annotate.JsonSerialize;
+
+import java.util.ArrayList;
+
+/**
+ * 网络请求的消息体
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL)
+public class DcsRequestBody {
+ private ArrayList<ClientContext> clientContext;
+ private Event event;
+
+ public DcsRequestBody(Event event) {
+ this.event = event;
+ }
+
+ public void setClientContext(ArrayList<ClientContext> clientContexts) {
+ this.clientContext = clientContexts;
+ }
+
+ public ArrayList<ClientContext> getClientContext() {
+ return clientContext;
+ }
+
+ public void setEvent(Event event) {
+ this.event = event;
+ }
+
+ public Event getEvent() {
+ return event;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/DcsResponseBody.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+/**
+ * 服务器端返回应答
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class DcsResponseBody {
+ // 指令
+ private Directive directive;
+
+ public Directive getDirective() {
+ return directive;
+ }
+
+ public void setDirective(Directive directive) {
+ this.directive = directive;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/DcsStreamRequestBody.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+import com.baidu.duer.dcs.http.OkHttpMediaType;
+
+import java.io.IOException;
+
+import okhttp3.MediaType;
+import okhttp3.RequestBody;
+import okio.BufferedSink;
+import okio.Okio;
+import okio.Pipe;
+
+/**
+ * 流请求消息体
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class DcsStreamRequestBody extends RequestBody {
+ private final Pipe pipe = new Pipe(8192);
+ private final BufferedSink mSink = Okio.buffer(pipe.sink());
+
+ public BufferedSink sink() {
+ return mSink;
+ }
+
+ @Override
+ public MediaType contentType() {
+ return OkHttpMediaType.MEDIA_STREAM_TYPE;
+ }
+
+ @Override
+ public void writeTo(BufferedSink bufferedSink) throws IOException {
+ bufferedSink.writeAll(pipe.source());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/DialogRequestIdHeader.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+/**
+ * 带请求会话Id头部
+ * <p>
+ * Created by wuruisheng@baidu.com on 2017/5/31.
+ */
+public class DialogRequestIdHeader extends MessageIdHeader {
+ // 请求会话id
+ private String dialogRequestId;
+
+ public DialogRequestIdHeader() {
+
+ }
+
+ public DialogRequestIdHeader(String nameSpace, String name, String dialogRequestId) {
+ super(nameSpace, name);
+ this.dialogRequestId = dialogRequestId;
+ }
+
+ public final String getDialogRequestId() {
+ return dialogRequestId;
+ }
+
+ public final void setDialogRequestId(String dialogRequestId) {
+ this.dialogRequestId = dialogRequestId;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%1$s dialogRequestId:%2$s", super.toString(), dialogRequestId);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/Directive.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+import com.baidu.duer.dcs.util.ObjectMapperUtil;
+
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.JsonParseException;
+import org.codehaus.jackson.JsonParser;
+import org.codehaus.jackson.annotate.JsonIgnore;
+import org.codehaus.jackson.map.DeserializationContext;
+import org.codehaus.jackson.map.JsonDeserializer;
+import org.codehaus.jackson.map.JsonMappingException;
+import org.codehaus.jackson.map.ObjectReader;
+import org.codehaus.jackson.map.annotate.JsonDeserialize;
+import org.codehaus.jackson.node.ObjectNode;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * 指令类:服务端下发给设备端去执行
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+@JsonDeserialize(using = Directive.DirectiveDeserializer.class)
+public class Directive {
+ public Header header;
+ public Payload payload;
+
+ @JsonIgnore
+ public String rawMessage;
+
+
+ public Directive(Header header, JsonNode payload, String rawMessage) throws IOException {
+ this.header = header;
+ String namespace = header.getNamespace();
+ String name = header.getName();
+ Class<?> payloadType = PayloadConfig.getInstance().findPayloadClass(namespace, name);
+ if (null != payloadType) {
+ this.payload = ObjectMapperUtil.instance().getObjectReader().withType(payloadType).readValue(payload);
+ } else {
+ this.payload = new Payload();
+ }
+
+ this.rawMessage = rawMessage;
+ }
+
+ /**
+ * jackson反序列化directive对象
+ */
+ public static class DirectiveDeserializer extends JsonDeserializer<Directive> {
+ @Override
+ public Directive deserialize(JsonParser jp, DeserializationContext ctx)
+ throws IOException {
+ ObjectReader reader = ObjectMapperUtil.instance().getObjectReader();
+ ObjectNode obj = (ObjectNode) reader.readTree(jp);
+ Iterator<Map.Entry<String, JsonNode>> elementsIterator = obj.getFields();
+
+ String rawMessage = obj.toString();
+ DialogRequestIdHeader header = null;
+ JsonNode payloadNode = null;
+ ObjectReader headerReader =
+ ObjectMapperUtil.instance().getObjectReader(DialogRequestIdHeader.class);
+ while (elementsIterator.hasNext()) {
+ Map.Entry<String, JsonNode> element = elementsIterator.next();
+ if (element.getKey().equals("header")) {
+ header = headerReader.readValue(element.getValue());
+ }
+ if (element.getKey().equals("payload")) {
+ payloadNode = element.getValue();
+ }
+ }
+ if (header == null) {
+ throw ctx.mappingException("Missing header");
+ }
+ if (payloadNode == null) {
+ throw ctx.mappingException("Missing payload");
+ }
+
+ return createDirective(header, payloadNode, rawMessage);
+ }
+
+ private Directive createDirective(Header header, JsonNode payload, String rawMessage)
+ throws JsonParseException, JsonMappingException, IOException {
+ return new Directive(header, payload, rawMessage);
+ }
+ }
+
+ @JsonIgnore
+ public String getName() {
+ return header.getName();
+ }
+
+ public Payload getPayload() {
+ return payload;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/Event.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+/**
+ * 事件:设备端上发生任何事情,需要通过事件来通知服务端
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class Event extends BaseMessage {
+ public Event(Header header, Payload payload) {
+ super(header, payload);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/Header.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+/**
+ * header类
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public class Header {
+ private String namespace;
+ private String name;
+
+ public Header() {
+ }
+
+ public Header(String namespace, String name) {
+ setNamespace(namespace);
+ setName(name);
+ }
+
+ public final void setNamespace(String namespace) {
+ if (namespace == null) {
+ throw new IllegalArgumentException("Header namespace must not be null");
+ }
+ this.namespace = namespace;
+ }
+
+ public final void setName(String name) {
+ if (name == null) {
+ throw new IllegalArgumentException("Header name must not be null");
+ }
+ this.name = name;
+ }
+
+ public final String getNamespace() {
+ return namespace;
+ }
+
+ public final String getName() {
+ return name;
+ }
+
+ @Override
+ public String toString() {
+ return "Header{"
+ + "namespace='"
+ + namespace
+ + '\''
+ + ", name='"
+ + name
+ + '\''
+ + '}';
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/MessageIdHeader.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+import java.util.UUID;
+
+/**
+ * 带有MessageId的Header
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public class MessageIdHeader extends Header {
+ private String messageId;
+
+ public MessageIdHeader() {
+ super();
+ }
+
+ public MessageIdHeader(String nameSpace, String name) {
+ super(nameSpace, name);
+
+ messageId = UUID.randomUUID().toString();
+ }
+
+ public final void setMessageId(String messageId) {
+ this.messageId = messageId;
+ }
+
+ public final String getMessageId() {
+ return messageId;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%1$s id:%2$s", super.toString(), messageId);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/Payload.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+/**
+ * Payload基类
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public class Payload {
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/framework/message/PayloadConfig.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.framework.message;
+
+import com.baidu.duer.dcs.devicemodule.alerts.message.DeleteAlertPayload;
+import com.baidu.duer.dcs.devicemodule.alerts.message.SetAlertPayload;
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.ClearQueuePayload;
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.PlayPayload;
+import com.baidu.duer.dcs.devicemodule.audioplayer.message.StopPayload;
+import com.baidu.duer.dcs.devicemodule.screen.message.HtmlPayload;
+import com.baidu.duer.dcs.devicemodule.speakcontroller.message.AdjustVolumePayload;
+import com.baidu.duer.dcs.devicemodule.speakcontroller.message.SetMutePayload;
+import com.baidu.duer.dcs.devicemodule.speakcontroller.message.SetVolumePayload;
+import com.baidu.duer.dcs.devicemodule.system.message.SetEndPointPayload;
+import com.baidu.duer.dcs.devicemodule.system.message.ThrowExceptionPayload;
+import com.baidu.duer.dcs.devicemodule.voiceinput.message.ListenPayload;
+import com.baidu.duer.dcs.devicemodule.voiceoutput.message.SpeakPayload;
+
+import java.util.HashMap;
+
+/**
+ * 利用namespace和name做为key存储不同payload子类class并且find
+ * <p>
+ * Created by wuruisheng on 2017/6/1.
+ */
+public class PayloadConfig {
+ private final HashMap<String, Class<?>> payloadClass;
+
+ private static class PayloadConfigHolder {
+ private static final PayloadConfig instance = new PayloadConfig();
+ }
+
+ public static PayloadConfig getInstance() {
+ return PayloadConfigHolder.instance;
+ }
+
+ private PayloadConfig() {
+ payloadClass = new HashMap<>();
+
+ // AudioInputImpl
+ String namespace = com.baidu.duer.dcs.devicemodule.voiceinput.ApiConstants.NAMESPACE;
+ String name = com.baidu.duer.dcs.devicemodule.voiceinput.ApiConstants.Directives.Listen.NAME;
+ insertPayload(namespace, name, ListenPayload.class);
+
+ // VoiceOutput
+ namespace = com.baidu.duer.dcs.devicemodule.voiceoutput.ApiConstants.NAMESPACE;
+ name = com.baidu.duer.dcs.devicemodule.voiceoutput.ApiConstants.Directives.Speak.NAME;
+ insertPayload(namespace, name, SpeakPayload.class);
+
+ // audio
+ namespace = com.baidu.duer.dcs.devicemodule.audioplayer.ApiConstants.NAMESPACE;
+ name = com.baidu.duer.dcs.devicemodule.audioplayer.ApiConstants.Directives.Play.NAME;
+ insertPayload(namespace, name, PlayPayload.class);
+
+ name = com.baidu.duer.dcs.devicemodule.audioplayer.ApiConstants.Directives.Stop.NAME;
+ insertPayload(namespace, name, StopPayload.class);
+
+ name = com.baidu.duer.dcs.devicemodule.audioplayer.ApiConstants.Directives.ClearQueue.NAME;
+ insertPayload(namespace, name, ClearQueuePayload.class);
+
+ // alert
+ namespace = com.baidu.duer.dcs.devicemodule.alerts.ApiConstants.NAMESPACE;
+ name = com.baidu.duer.dcs.devicemodule.alerts.ApiConstants.Directives.SetAlert.NAME;
+ insertPayload(namespace, name, SetAlertPayload.class);
+
+ name = com.baidu.duer.dcs.devicemodule.alerts.ApiConstants.Directives.DeleteAlert.NAME;
+ insertPayload(namespace, name, DeleteAlertPayload.class);
+
+ // SpeakController
+ namespace = com.baidu.duer.dcs.devicemodule.speakcontroller.ApiConstants.NAMESPACE;
+ name = com.baidu.duer.dcs.devicemodule.speakcontroller.ApiConstants.Directives.SetVolume.NAME;
+ insertPayload(namespace, name, SetVolumePayload.class);
+
+ name = com.baidu.duer.dcs.devicemodule.speakcontroller.ApiConstants.Directives.AdjustVolume.NAME;
+ insertPayload(namespace, name, AdjustVolumePayload.class);
+
+ name = com.baidu.duer.dcs.devicemodule.speakcontroller.ApiConstants.Directives.SetMute.NAME;
+ insertPayload(namespace, name, SetMutePayload.class);
+
+ // System
+ namespace = com.baidu.duer.dcs.devicemodule.system.ApiConstants.NAMESPACE;
+ name = com.baidu.duer.dcs.devicemodule.system.ApiConstants.Directives.SetEndpoint.NAME;
+ insertPayload(namespace, name, SetEndPointPayload.class);
+
+ name = com.baidu.duer.dcs.devicemodule.system.ApiConstants.Directives.ThrowException.NAME;
+ insertPayload(namespace, name, ThrowExceptionPayload.class);
+
+ // Screen
+ namespace = com.baidu.duer.dcs.devicemodule.screen.ApiConstants.NAMESPACE;
+ name = com.baidu.duer.dcs.devicemodule.screen.ApiConstants.Directives.HtmlView.NAME;
+ insertPayload(namespace, name, HtmlPayload.class);
+ }
+
+ void insertPayload(String namespace, String name, Class<?> type) {
+ final String key = namespace + name;
+ payloadClass.put(key, type);
+ }
+
+ Class<?> findPayloadClass(String namespace, String name) {
+ final String key = namespace + name;
+ return payloadClass.get(key);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/DcsHttpManager.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http;
+
+import com.baidu.duer.dcs.http.builder.GetBuilder;
+import com.baidu.duer.dcs.http.builder.PostMultipartBuilder;
+import com.baidu.duer.dcs.http.callback.DcsCallback;
+import com.baidu.duer.dcs.http.intercepter.LoggingInterceptor;
+import com.baidu.duer.dcs.http.request.RequestCall;
+import com.baidu.duer.dcs.http.utils.Platform;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.Call;
+import okhttp3.OkHttpClient;
+import okhttp3.Response;
+
+/**
+ * 网络请求-单例
+ * <p>
+ * Created by zhangyan@baidu.com on 2017/5/15.
+ */
+public class DcsHttpManager {
+ // 默认时间,比如超时时间
+ public static final long DEFAULT_MILLISECONDS = 60 * 1000L;
+ private OkHttpClient mOkHttpClient;
+ private Platform mPlatform;
+
+ private static class DcsHttpManagerHolder {
+ private static final DcsHttpManager INSTANCE = new DcsHttpManager();
+ }
+
+ public static DcsHttpManager getInstance() {
+ return DcsHttpManagerHolder.INSTANCE;
+ }
+
+ private DcsHttpManager() {
+ if (mOkHttpClient == null) {
+ // http数据log,日志中打印出HTTP请求&响应数据
+ // HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
+ // 包含header、body数据
+ mOkHttpClient = new OkHttpClient.Builder()
+ .retryOnConnectionFailure(false)
+ .readTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS)
+ .writeTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS)
+ .connectTimeout(DEFAULT_MILLISECONDS, TimeUnit.MILLISECONDS)
+ // .addInterceptor(new RetryInterceptor(3))
+ .addInterceptor(new LoggingInterceptor())
+ // .connectionPool(new ConnectionPool(0, 1, TimeUnit.NANOSECONDS))
+ .build();
+ }
+ mPlatform = Platform.get();
+ }
+
+ public OkHttpClient getOkHttpClient() {
+ return mOkHttpClient;
+ }
+
+ public static GetBuilder get() {
+ return new GetBuilder();
+ }
+
+ public static PostMultipartBuilder post() {
+ return new PostMultipartBuilder();
+ }
+
+ public void execute(final RequestCall requestCall, DcsCallback dcsCallback) {
+
+ if (dcsCallback == null) {
+ dcsCallback = DcsCallback.backDefaultCallBack;
+ }
+ final DcsCallback finalDCSCallback = dcsCallback;
+ final int id = requestCall.getOkHttpRequest().getId();
+
+ requestCall.getCall().enqueue(new okhttp3.Callback() {
+ @Override
+ public void onFailure(Call call, final IOException e) {
+ sendFailResultCallback(call, e, finalDCSCallback, id);
+ }
+
+ @Override
+ public void onResponse(final Call call, final Response response) {
+ try {
+ if (call.isCanceled()) {
+ sendFailResultCallback(call, new IOException("Canceled!"), finalDCSCallback, id);
+ return;
+ }
+ if (!finalDCSCallback.validateResponse(response, id)) {
+ IOException exception = new IOException("request failed , response's code is : "
+ + response.code());
+ sendFailResultCallback(call, exception, finalDCSCallback, id);
+ return;
+ }
+ sendSuccessResultCallback(response, finalDCSCallback, id);
+ Object o = finalDCSCallback.parseNetworkResponse(response, id);
+ } catch (Exception e) {
+ sendFailResultCallback(call, e, finalDCSCallback, id);
+ } finally {
+ if (response.body() != null) {
+ response.body().close();
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * 网络请求失败处理
+ *
+ * @param call okhttp的请求call
+ * @param e 异常信息
+ * @param dcsCallback 回调
+ * @param id 请求标识
+ */
+ private void sendFailResultCallback(final Call call,
+ final Exception e,
+ final DcsCallback dcsCallback,
+ final int id) {
+ if (dcsCallback == null) {
+ return;
+ }
+ mPlatform.execute(new Runnable() {
+ @Override
+ public void run() {
+ dcsCallback.onError(call, e, id);
+ dcsCallback.onAfter(id);
+ }
+ });
+ }
+
+ /**
+ * 网络请求成功处理
+ *
+ * @param object object 返回的对象
+ * @param dcsCallback dcsCallback 回调
+ * @param id id 请求标识
+ */
+ private void sendSuccessResultCallback(final Object object,
+ final DcsCallback dcsCallback,
+ final int id) {
+ if (dcsCallback == null) {
+ return;
+ }
+ mPlatform.execute(new Runnable() {
+ @Override
+ public void run() {
+ dcsCallback.onResponse(object, id);
+ dcsCallback.onAfter(id);
+ }
+ });
+ }
+
+ /**
+ * 取消请求
+ *
+ * @param tag 请求的时候设置的tag
+ */
+ public void cancelTag(Object tag) {
+ for (Call call : mOkHttpClient.dispatcher().queuedCalls()) {
+ if (tag.equals(call.request().tag())) {
+ call.cancel();
+ }
+ }
+ for (Call call : mOkHttpClient.dispatcher().runningCalls()) {
+ if (tag.equals(call.request().tag())) {
+ call.cancel();
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/HttpConfig.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http;
+
+import com.baidu.duer.dcs.util.CommonUtil;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * HttpConfig
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/1.
+ */
+public class HttpConfig {
+ // 请求https
+ public static final String HTTP_PREFIX = "https://";
+ // 请求host
+ public static final String HOST = "dueros-h2.baidu.com";
+ public static String endpoint = null;
+ // 请求event事件
+ public static final String EVENTS = "/dcs/v1/events";
+ // 请求directives事件
+ public static final String DIRECTIVES = "/dcs/v1/directives";
+ // ping
+ public static final String PING = "/dcs/v1/ping";
+ // 请求event事件TAG
+ public static final String HTTP_EVENT_TAG = "event";
+ // 请求directives事件TAG
+ public static final String HTTP_DIRECTIVES_TAG = "directives";
+ // 请求ping的TAG
+ public static final String HTTP_PING_TAG = "ping";
+
+ public static String getEndpoint() {
+ if (null == endpoint || "".equals(endpoint)) {
+ endpoint = HTTP_PREFIX + HOST;
+ }
+ return endpoint;
+ }
+
+ public static void setEndpoint(String endpoint) {
+ HttpConfig.endpoint = endpoint;
+ }
+
+ public static String getEventsUrl() {
+ return getEndpoint() + EVENTS;
+ }
+
+ public static String getDirectivesUrl() {
+ return getEndpoint() + DIRECTIVES;
+ }
+
+ public static String getPingUrl() {
+ return getEndpoint() + PING;
+ }
+
+ public static class HttpHeaders {
+ public static final String CONTENT_TYPE = "Content-Type";
+ public static final String DUEROS_DEVICE_ID = "dueros-device-id";
+ public static final String AUTHORIZATION = "Authorization";
+ public static final String CONTENT_ID = "Content-ID";
+ public static final String BEARER = "Bearer ";
+ public static final String DEBUG = "debug";
+ public static final String DEBUG_PARAM = "0";
+ }
+
+ public static class ContentTypes {
+ public static final String JSON = "application/json";
+ public static final String FORM_MULTIPART = "multipart/form-data boundary=dumi-boundory";
+ public static final String APPLICATION_JSON = JSON + ";" + " charset=UTF-8";
+ public static final String APPLICATION_AUDIO = "application/octet-stream";
+ }
+
+ public static class Parameters {
+ public static final String BOUNDARY = "boundary";
+ public static final String DATA_METADATA = "metadata";
+ public static final String DATA_AUDIO = "audio";
+ }
+
+ public static String accessToken = "";
+
+ public static String getAccessToken() {
+ return accessToken;
+ }
+
+ public static void setAccessToken(String accessToken) {
+ HttpConfig.accessToken = accessToken;
+ }
+
+ /**
+ * 获取dcs的headers
+ *
+ * @return header集合
+ */
+ public static Map<String, String> getDCSHeaders() {
+ Map<String, String> headers = new HashMap<>();
+ headers.put(HttpConfig.HttpHeaders.AUTHORIZATION,
+ HttpConfig.HttpHeaders.BEARER + getAccessToken());
+ headers.put(HttpConfig.HttpHeaders.CONTENT_TYPE,
+ HttpConfig.ContentTypes.FORM_MULTIPART);
+ headers.put(HttpConfig.HttpHeaders.DUEROS_DEVICE_ID,
+ CommonUtil.getDeviceUniqueID());
+ headers.put(HttpConfig.HttpHeaders.DEBUG,
+ HttpConfig.HttpHeaders.DEBUG_PARAM);
+ return headers;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/HttpRequestInterface.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http;
+
+import com.baidu.duer.dcs.framework.message.DcsRequestBody;
+import com.baidu.duer.dcs.framework.message.DcsStreamRequestBody;
+import com.baidu.duer.dcs.http.callback.DcsCallback;
+
+/**
+ * 网络请求工具接口
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/1.
+ */
+public interface HttpRequestInterface {
+ /**
+ * 异步Post EventString请求
+ *
+ * @param requestBody 请求信息体
+ * @param dcsCallback 结果回调接口
+ */
+ void doPostEventStringAsync(DcsRequestBody requestBody, DcsCallback dcsCallback);
+
+ /**
+ * 异步PostMultipart请求
+ *
+ * @param requestBody 请求信息体
+ * @param streamRequestBody 请求信息体stream
+ * @param dcsCallback 结果回调接口
+ */
+ void doPostEventMultipartAsync(DcsRequestBody requestBody,
+ DcsStreamRequestBody streamRequestBody,
+ DcsCallback dcsCallback);
+
+ /**
+ * 异步Get Directives请求
+ *
+ * @param requestBody 请求信息体
+ * @param dcsCallback 结果回调接口
+ */
+ void doGetDirectivesAsync(DcsRequestBody requestBody, DcsCallback dcsCallback);
+
+ /**
+ * 异步Get Ping请求
+ *
+ * @param requestBody 请求信息体
+ * @param dcsCallback 结果回调接口
+ */
+ void doGetPingAsync(DcsRequestBody requestBody, DcsCallback dcsCallback);
+
+ /**
+ * 取消请求
+ *
+ * @param requestTag 请求标识
+ */
+ void cancelRequest(Object requestTag);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/OkHttpMediaType.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http;
+
+import okhttp3.MediaType;
+
+import static com.baidu.duer.dcs.http.HttpConfig.ContentTypes.APPLICATION_AUDIO;
+import static com.baidu.duer.dcs.http.HttpConfig.ContentTypes.APPLICATION_JSON;
+
+/**
+ * okhttp media_type
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/1.
+ */
+public class OkHttpMediaType {
+ // json类型
+ public static final MediaType MEDIA_JSON_TYPE = MediaType.parse(APPLICATION_JSON);
+ // 数据流类型
+ public static final MediaType MEDIA_STREAM_TYPE = MediaType.parse(APPLICATION_AUDIO);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/OkHttpRequestImpl.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http;
+
+import com.baidu.duer.dcs.framework.message.DcsRequestBody;
+import com.baidu.duer.dcs.framework.message.DcsStreamRequestBody;
+import com.baidu.duer.dcs.http.callback.DcsCallback;
+import com.baidu.duer.dcs.util.LogUtil;
+import com.baidu.duer.dcs.util.ObjectMapperUtil;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import okhttp3.RequestBody;
+
+/**
+ * 请求实现
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/2.
+ */
+public class OkHttpRequestImpl implements HttpRequestInterface {
+ private static final String TAG = "OkHttpRequestImpl";
+ private final DcsHttpManager dcsHttpManager;
+
+ public OkHttpRequestImpl() {
+ dcsHttpManager = DcsHttpManager.getInstance();
+ }
+
+ @Override
+ public void doPostEventStringAsync(DcsRequestBody requestBody, DcsCallback dcsCallback) {
+ String bodyJson = ObjectMapperUtil.instance().objectToJson(requestBody);
+ LogUtil.d(TAG, "doPostEventStringAsync-bodyJson:" + bodyJson);
+ Map<String, RequestBody> multiParts = new LinkedHashMap<>();
+ multiParts.put(HttpConfig.Parameters.DATA_METADATA,
+ RequestBody.create(OkHttpMediaType.MEDIA_JSON_TYPE, bodyJson));
+ DcsHttpManager.post()
+ .url(HttpConfig.getEventsUrl())
+ .headers(HttpConfig.getDCSHeaders())
+ .multiParts(multiParts)
+ .tag(HttpConfig.HTTP_EVENT_TAG)
+ .build()
+ .execute(dcsCallback);
+ }
+
+ @Override
+ public void doPostEventMultipartAsync(DcsRequestBody requestBody,
+ DcsStreamRequestBody streamRequestBody,
+ DcsCallback dcsCallback) {
+ String bodyJson = ObjectMapperUtil.instance().objectToJson(requestBody);
+ LogUtil.d(TAG, "doPostEventMultipartAsync-bodyJson:" + bodyJson);
+ Map<String, RequestBody> multiParts = new LinkedHashMap<>();
+ multiParts.put(HttpConfig.Parameters.DATA_METADATA,
+ RequestBody.create(OkHttpMediaType.MEDIA_JSON_TYPE, bodyJson));
+ multiParts.put(HttpConfig.Parameters.DATA_AUDIO, streamRequestBody);
+ DcsHttpManager.post()
+ .url(HttpConfig.getEventsUrl())
+ .headers(HttpConfig.getDCSHeaders())
+ .multiParts(multiParts)
+ .tag(HttpConfig.HTTP_EVENT_TAG)
+ .build()
+ .execute(dcsCallback);
+ }
+
+ @Override
+ public void doGetDirectivesAsync(DcsRequestBody requestBody, DcsCallback dcsCallback) {
+ LogUtil.d(TAG, "doGetDirectivesAsync");
+ final long time = 60 * 60 * 1000L;
+ DcsHttpManager.get()
+ .url(HttpConfig.getDirectivesUrl())
+ .headers(HttpConfig.getDCSHeaders())
+ .tag(HttpConfig.HTTP_DIRECTIVES_TAG)
+ .build()
+ .connTimeOut(time)
+ .readTimeOut(time)
+ .writeTimeOut(time)
+ .execute(dcsCallback);
+ }
+
+ @Override
+ public void doGetPingAsync(DcsRequestBody requestBody, DcsCallback dcsCallback) {
+ LogUtil.d(TAG, "doGetPingAsync");
+ DcsHttpManager.get()
+ .url(HttpConfig.getPingUrl())
+ .headers(HttpConfig.getDCSHeaders())
+ .tag(HttpConfig.HTTP_PING_TAG)
+ .build()
+ .execute(dcsCallback);
+ }
+
+ @Override
+ public void cancelRequest(Object requestTag) {
+ dcsHttpManager.cancelTag(requestTag);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/builder/GetBuilder.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.builder;
+
+import android.net.Uri;
+
+import com.baidu.duer.dcs.http.request.GetRequest;
+import com.baidu.duer.dcs.http.request.RequestCall;
+
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * get请求构建
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/15.
+ */
+public class GetBuilder extends OkHttpRequestBuilder<GetBuilder> implements HasParamInterface {
+ @Override
+ public RequestCall build() {
+ if (params != null) {
+ url = appendParams(url, params);
+ }
+ return new GetRequest(url, tag, params, headers, id).build();
+ }
+
+ /**
+ * 添加参数到url上
+ *
+ * @param url url 请求的url
+ * @param params params 参数集合
+ * @return url 拼接后的url
+ */
+ protected String appendParams(String url, Map<String, String> params) {
+ if (url == null || params == null || params.isEmpty()) {
+ return url;
+ }
+ Uri.Builder builder = Uri.parse(url).buildUpon();
+ Set<String> keys = params.keySet();
+ Iterator<String> iterator = keys.iterator();
+ while (iterator.hasNext()) {
+ String key = iterator.next();
+ builder.appendQueryParameter(key, params.get(key));
+ }
+ return builder.build().toString();
+ }
+
+
+ @Override
+ public GetBuilder params(Map<String, String> params) {
+ this.params = params;
+ return this;
+ }
+
+ @Override
+ public GetBuilder addParams(String key, String val) {
+ if (this.params == null) {
+ params = new LinkedHashMap<>();
+ }
+ params.put(key, val);
+ return this;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/builder/HasParamInterface.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.builder;
+
+import java.util.Map;
+
+/**
+ * 请求是否包含参数
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/15.
+ */
+public interface HasParamInterface {
+ /**
+ * 构建请求参数
+ *
+ * @param params 请求参数
+ * @return OkHttpRequestBuilder
+ */
+ OkHttpRequestBuilder params(Map<String, String> params);
+
+ /**
+ * @param key 请求参数的key
+ * @param val 请求参数的值
+ * @return OkHttpRequestBuilder
+ */
+ OkHttpRequestBuilder addParams(String key, String val);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/builder/OkHttpRequestBuilder.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.builder;
+
+import com.baidu.duer.dcs.http.request.RequestCall;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * 请求构建基类
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/15.
+ */
+public abstract class OkHttpRequestBuilder<T extends OkHttpRequestBuilder> {
+ // 请求url
+ protected String url;
+ // 请求tag
+ protected Object tag;
+ // 请求的headers
+ protected Map<String, String> headers;
+ // 请求的参数集合
+ protected Map<String, String> params;
+ // 请求的表识id
+ protected int id;
+
+ public T id(int id) {
+ this.id = id;
+ return (T) this;
+ }
+
+ public T url(String url) {
+ this.url = url;
+ return (T) this;
+ }
+
+
+ public T tag(Object tag) {
+ this.tag = tag;
+ return (T) this;
+ }
+
+ public T headers(Map<String, String> headers) {
+ this.headers = headers;
+ return (T) this;
+ }
+
+ public T addHeader(String key, String val) {
+ if (this.headers == null) {
+ headers = new LinkedHashMap<>();
+ }
+ headers.put(key, val);
+ return (T) this;
+ }
+
+ /**
+ * 构建请求
+ *
+ * @return RequestCall
+ */
+ public abstract RequestCall build();
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/builder/PostMultipartBuilder.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.builder;
+
+import com.baidu.duer.dcs.http.request.PostMultipartRequest;
+import com.baidu.duer.dcs.http.request.RequestCall;
+
+import java.io.Serializable;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.Map;
+
+import okhttp3.RequestBody;
+
+/**
+ * post请求多part构建
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/15.
+ */
+public class PostMultipartBuilder extends OkHttpRequestBuilder<PostMultipartBuilder>
+ implements HasParamInterface {
+ private LinkedList<Multipart> multiParts = new LinkedList<>();
+
+ @Override
+ public RequestCall build() {
+ return new PostMultipartRequest(url, tag, params, headers, multiParts, id).build();
+ }
+
+ @Override
+ public PostMultipartBuilder params(Map<String, String> params) {
+ this.params = params;
+ return this;
+ }
+
+ @Override
+ public PostMultipartBuilder addParams(String key, String val) {
+ if (this.params == null) {
+ params = new LinkedHashMap<>();
+ }
+ params.put(key, val);
+ return this;
+ }
+
+ /**
+ * 添加多个Multipart
+ *
+ * @param map map集合
+ * @return 当前对象
+ */
+ public PostMultipartBuilder multiParts(Map<String, RequestBody> map) {
+ if (map != null) {
+ multiParts = new LinkedList<>();
+ }
+ for (String k : map.keySet()) {
+ this.multiParts.add(new Multipart(k, map.get(k)));
+ }
+ return this;
+ }
+
+ /**
+ * 添加一个Multipart
+ *
+ * @param name name
+ * @param body body
+ * @return 当前对象
+ */
+ public PostMultipartBuilder addMultiPart(String name, RequestBody body) {
+ multiParts.add(new Multipart(name, body));
+ return this;
+ }
+
+ /**
+ * 请求体body-Multipart
+ */
+ public static final class Multipart implements Serializable {
+ // body的key
+ public String key;
+ // body的内容
+ public RequestBody requestBody;
+
+ public Multipart(String name, RequestBody requestBody) {
+ this.key = name;
+ this.requestBody = requestBody;
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/builder/PostStringBuilder.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.builder;
+
+import com.baidu.duer.dcs.http.request.PostStringRequest;
+import com.baidu.duer.dcs.http.request.RequestCall;
+
+import okhttp3.MediaType;
+
+/**
+ * post请求的构建类
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/16.
+ */
+public class PostStringBuilder extends OkHttpRequestBuilder<PostStringBuilder> {
+ // 内容
+ private String content;
+ // 类型
+ private MediaType mediaType;
+
+ public PostStringBuilder content(String content) {
+ this.content = content;
+ return this;
+ }
+
+ public PostStringBuilder mediaType(MediaType mediaType) {
+ this.mediaType = mediaType;
+ return this;
+ }
+
+ @Override
+ public RequestCall build() {
+ return new PostStringRequest(url, tag, params, headers, content, mediaType, id).build();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/callback/DcsCallback.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.callback;
+
+import okhttp3.Call;
+import okhttp3.Request;
+import okhttp3.Response;
+
+/**
+ * 网络回调基类
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/2.
+ */
+public abstract class DcsCallback<T> {
+ /**
+ * UI线程
+ *
+ * @param request 请求
+ * @param id 请求id
+ */
+ public void onBefore(Request request, int id) {
+ }
+
+ /**
+ * UI线程
+ *
+ * @param id 请求id
+ */
+ public void onAfter(int id) {
+ }
+
+ public static DcsCallback backDefaultCallBack = new DcsCallback() {
+
+ @Override
+ public Object parseNetworkResponse(Response response, int id) throws Exception {
+ return null;
+ }
+
+ @Override
+ public void onError(Call call, Exception e, int id) {
+
+ }
+
+ @Override
+ public void onResponse(Object response, int id) {
+
+ }
+ };
+
+ public boolean validateResponse(Response response, int id) {
+ return response.isSuccessful();
+ }
+
+ /**
+ * 非UI线程
+ *
+ * @param response response
+ */
+ public abstract T parseNetworkResponse(Response response, int id) throws Exception;
+
+ /**
+ * 错误处理,UI线程
+ *
+ * @param call call
+ * @param e e 错误异常信息
+ * @param id id 请求id
+ */
+ public abstract void onError(Call call, Exception e, int id);
+
+ /**
+ * 数据回调,UI线程
+ *
+ * @param response response
+ * @param id id
+ */
+ public abstract void onResponse(T response, int id);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/callback/ResponseCallback.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.callback;
+
+import com.baidu.duer.dcs.util.LogUtil;
+
+import okhttp3.Call;
+import okhttp3.Response;
+
+/**
+ * framework 返回数据类
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/2.
+ */
+public class ResponseCallback extends DcsCallback<Response> {
+ private static final String TAG = "ResponseCallback";
+
+ @Override
+ public Response parseNetworkResponse(Response response, int id) throws Exception {
+ return response;
+ }
+
+ @Override
+ public void onError(Call call, Exception e, int id) {
+ LogUtil.d(TAG, "onError:" + e.getMessage());
+ }
+
+ @Override
+ public void onResponse(Response response, int id) {
+ LogUtil.d(TAG, "onResponse:" + response.code());
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/callback/StreamDcsCallback.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.callback;
+
+import java.io.InputStream;
+
+import okhttp3.Response;
+
+/**
+ * 数据流回调
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/2.
+ */
+public abstract class StreamDcsCallback extends DcsCallback<InputStream> {
+ @Override
+ public InputStream parseNetworkResponse(Response response, int id) throws Exception {
+ return response.body().byteStream();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/callback/StringDcsCallback.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.callback;
+
+import okhttp3.Response;
+
+/**
+ * String类型回调
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/2.
+ */
+public abstract class StringDcsCallback extends DcsCallback<String> {
+ @Override
+ public String parseNetworkResponse(Response response, int id) throws Exception {
+ return response.body().string();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/exceptions/Exceptions.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.exceptions;
+
+/**
+ * 网络模块的异常处理,比如参数检查
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/15.
+ */
+public class Exceptions {
+ public static void illegalArgument(String msg, Object... params) {
+ throw new IllegalArgumentException(String.format(msg, params));
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/intercepter/LoggingInterceptor.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.intercepter;
+
+import com.baidu.duer.dcs.util.LogUtil;
+
+import java.io.IOException;
+import java.util.Locale;
+
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+
+/**
+ * http Interceptor 拦截打印http-log
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/25.
+ */
+public class LoggingInterceptor implements Interceptor {
+ private static final String TAG = "HttpLog";
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+ long t1 = System.nanoTime();
+ LogUtil.d(TAG, String.format("request: %s [%s] %s%n%s",
+ request.method(), request.url(), chain.connection(), request.headers()));
+
+ Response response = chain.proceed(request);
+ long t2 = System.nanoTime();
+ LogUtil.d(TAG, String.format(Locale.CANADA, "response: %d [%s] %.1fms%n%s",
+ response.code(), response.request().url(), (t2 - t1) / 1e6d, response.headers()));
+ return response;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/intercepter/RetryInterceptor.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.intercepter;
+
+import java.io.IOException;
+
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+
+/**
+ * 重试拦截器
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/20.
+ */
+public class RetryInterceptor implements Interceptor {
+ // 最大重试次数,假如设置为3次重试的话,则最大可能请求4次(默认1次+3次重试)
+ private int maxRetry;
+ private int retryNum = 0;
+
+ public RetryInterceptor(int maxRetry) {
+ this.maxRetry = maxRetry;
+ }
+
+ @Override
+ public Response intercept(Chain chain) throws IOException {
+ Request request = chain.request();
+ Response response = chain.proceed(request);
+ while (!response.isSuccessful() && retryNum < maxRetry) {
+ retryNum++;
+ response = chain.proceed(request);
+ }
+ return response;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/request/GetRequest.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.request;
+
+import java.util.Map;
+
+import okhttp3.Request;
+import okhttp3.RequestBody;
+
+/**
+ * 普通GetRequest
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/15.
+ */
+public class GetRequest extends OkHttpRequest {
+ public GetRequest(String url,
+ Object tag,
+ Map<String, String> params,
+ Map<String, String> headers,
+ int id) {
+ super(url, tag, params, headers, id);
+ }
+
+ @Override
+ protected RequestBody buildRequestBody() {
+ return null;
+ }
+
+ @Override
+ protected Request buildRequest(RequestBody requestBody) {
+ return builder.get().build();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/request/OkHttpRequest.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.request;
+
+import com.baidu.duer.dcs.http.callback.DcsCallback;
+import com.baidu.duer.dcs.http.exceptions.Exceptions;
+
+import java.util.Map;
+
+import okhttp3.Headers;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+
+/**
+ * 请求基类
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/15.
+ */
+public abstract class OkHttpRequest {
+ // url
+ protected String url;
+ // 用于取消请求的tag
+ protected Object tag;
+ // 请求参数
+ protected Map<String, String> params;
+ // 请求header
+ protected Map<String, String> headers;
+ // 请求的标识id
+ protected int id;
+ // okhttp的请求构建类
+ protected Request.Builder builder = new Request.Builder();
+
+ protected OkHttpRequest(String url, Object tag,
+ Map<String, String> params,
+ Map<String, String> headers,
+ int id) {
+ this.url = url;
+ this.tag = tag;
+ this.params = params;
+ this.headers = headers;
+ this.id = id;
+ if (url == null) {
+ Exceptions.illegalArgument("url can not be null.");
+ }
+ initBuilder();
+ }
+
+ /**
+ * 初始化okhttp的请求builder
+ */
+ private void initBuilder() {
+ builder.url(url).tag(tag);
+ appendHeaders();
+ }
+
+ /**
+ * 拼接请求的Header
+ */
+ protected void appendHeaders() {
+ Headers.Builder headerBuilder = new Headers.Builder();
+ if (headers == null || headers.isEmpty()) {
+ return;
+ }
+ for (String key : headers.keySet()) {
+ headerBuilder.add(key, headers.get(key));
+ }
+ builder.headers(headerBuilder.build());
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ public RequestCall build() {
+ return new RequestCall(this);
+ }
+
+ public Request generateRequest(DcsCallback dcsCallback) {
+ RequestBody requestBody = buildRequestBody();
+ RequestBody wrappedRequestBody = wrapRequestBody(requestBody, dcsCallback);
+ Request request = buildRequest(wrappedRequestBody);
+ return request;
+ }
+
+ protected RequestBody wrapRequestBody(RequestBody requestBody, final DcsCallback dcsCallback) {
+ return requestBody;
+ }
+
+ protected abstract RequestBody buildRequestBody();
+
+ protected abstract Request buildRequest(RequestBody requestBody);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/request/PostMultipartRequest.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.request;
+
+import com.baidu.duer.dcs.http.builder.PostMultipartBuilder;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import okhttp3.Headers;
+import okhttp3.MultipartBody;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+
+/**
+ * 用于post multipart请求
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/15.
+ */
+public class PostMultipartRequest extends OkHttpRequest {
+ private List<PostMultipartBuilder.Multipart> multiParts;
+
+ public PostMultipartRequest(String url,
+ Object tag,
+ Map<String, String> params,
+ Map<String, String> headers,
+ LinkedList<PostMultipartBuilder.Multipart> multiParts,
+ int id) {
+ super(url, tag, params, headers, id);
+ this.multiParts = multiParts;
+ }
+
+ @Override
+ protected RequestBody buildRequestBody() {
+ MultipartBody.Builder builder = new MultipartBody.Builder()
+ .setType(MultipartBody.FORM);
+ addParams(builder);
+ return builder.build();
+ }
+
+ @Override
+ protected Request buildRequest(RequestBody requestBody) {
+ return builder.post(requestBody).build();
+ }
+
+ private void addParams(MultipartBody.Builder builder) {
+ if (multiParts != null && !multiParts.isEmpty()) {
+ for (int i = 0; i < multiParts.size(); i++) {
+ PostMultipartBuilder.Multipart part = multiParts.get(i);
+ builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + part.key + "\""),
+ part.requestBody);
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/request/PostStringRequest.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.request;
+
+import com.baidu.duer.dcs.http.exceptions.Exceptions;
+
+import java.util.Map;
+
+import okhttp3.MediaType;
+import okhttp3.Request;
+import okhttp3.RequestBody;
+
+/**
+ * 用于发送字符串请求
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/16.
+ */
+public class PostStringRequest extends OkHttpRequest {
+ private static MediaType MEDIA_TYPE_PLAIN = MediaType.parse("text/plain;charset=utf-8");
+ private String content;
+ private MediaType mediaType;
+
+ public PostStringRequest(String url,
+ Object tag,
+ Map<String, String> params,
+ Map<String, String> headers,
+ String content,
+ MediaType mediaType,
+ int id) {
+ super(url, tag, params, headers, id);
+ this.content = content;
+ this.mediaType = mediaType;
+ if (this.content == null) {
+ Exceptions.illegalArgument("the content can not be null !");
+ }
+ if (this.mediaType == null) {
+ this.mediaType = MEDIA_TYPE_PLAIN;
+ }
+ }
+
+ @Override
+ protected RequestBody buildRequestBody() {
+ return RequestBody.create(mediaType, content);
+ }
+
+ @Override
+ protected Request buildRequest(RequestBody requestBody) {
+ return builder.post(requestBody).build();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/request/RequestCall.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.request;
+
+import com.baidu.duer.dcs.http.DcsHttpManager;
+import com.baidu.duer.dcs.http.callback.DcsCallback;
+
+import java.util.concurrent.TimeUnit;
+
+import okhttp3.Call;
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+
+/**
+ * 请求设置
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/15.
+ */
+public class RequestCall {
+ private OkHttpRequest okHttpRequest;
+ private Request request;
+ private Call call;
+ private OkHttpClient clone;
+ // 读取超时时间
+ private long readTimeOut;
+ // 写入数据超时时间
+ private long writeTimeOut;
+ // 连接超时时间
+ private long connTimeOut;
+
+ public RequestCall(OkHttpRequest request) {
+ this.okHttpRequest = request;
+ }
+
+ public RequestCall readTimeOut(long readTimeOut) {
+ this.readTimeOut = readTimeOut;
+ return this;
+ }
+
+ public RequestCall writeTimeOut(long writeTimeOut) {
+ this.writeTimeOut = writeTimeOut;
+ return this;
+ }
+
+ public RequestCall connTimeOut(long connTimeOut) {
+ this.connTimeOut = connTimeOut;
+ return this;
+ }
+
+ /**
+ * 构建请求
+ *
+ * @param dcsCallback 回调
+ * @return Call
+ */
+ public Call buildCall(DcsCallback dcsCallback) {
+ request = generateRequest(dcsCallback);
+ if (readTimeOut > 0 || writeTimeOut > 0 || connTimeOut > 0) {
+ readTimeOut = readTimeOut > 0 ? readTimeOut : DcsHttpManager.DEFAULT_MILLISECONDS;
+ writeTimeOut = writeTimeOut > 0 ? writeTimeOut : DcsHttpManager.DEFAULT_MILLISECONDS;
+ connTimeOut = connTimeOut > 0 ? connTimeOut : DcsHttpManager.DEFAULT_MILLISECONDS;
+ clone = DcsHttpManager.getInstance().getOkHttpClient().newBuilder()
+ .readTimeout(readTimeOut, TimeUnit.MILLISECONDS)
+ .writeTimeout(writeTimeOut, TimeUnit.MILLISECONDS)
+ .connectTimeout(connTimeOut, TimeUnit.MILLISECONDS)
+ .build();
+
+ call = clone.newCall(request);
+ } else {
+ call = DcsHttpManager.getInstance().getOkHttpClient().newCall(request);
+ }
+ return call;
+ }
+
+ private Request generateRequest(DcsCallback dcsCallback) {
+ return okHttpRequest.generateRequest(dcsCallback);
+ }
+
+ public void execute(DcsCallback dcsCallback) {
+ buildCall(dcsCallback);
+ if (dcsCallback != null) {
+ dcsCallback.onBefore(request, getOkHttpRequest().getId());
+ }
+ DcsHttpManager.getInstance().execute(this, dcsCallback);
+ }
+
+ public OkHttpRequest getOkHttpRequest() {
+ return okHttpRequest;
+ }
+
+ public Call getCall() {
+ return call;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/http/utils/Platform.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.http.utils;
+
+import android.os.Handler;
+import android.os.Looper;
+
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+/**
+ * 请求回调处理类
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/15.
+ */
+public class Platform {
+ private static final Platform PLATFORM = findPlatform();
+
+ public static Platform get() {
+ return PLATFORM;
+ }
+
+ private static Platform findPlatform() {
+ return new Android();
+ }
+
+ public Executor defaultCallbackExecutor() {
+ return Executors.newCachedThreadPool();
+ }
+
+ public void execute(Runnable runnable) {
+ defaultCallbackExecutor().execute(runnable);
+ }
+
+ /**
+ * android 平台下用于回调到UI线程的辅助类
+ */
+ private static final class Android extends Platform {
+ @Override
+ public Executor defaultCallbackExecutor() {
+ return new MainThreadExecutor();
+ }
+
+ static class MainThreadExecutor implements Executor {
+ private final Handler handler = new Handler(Looper.getMainLooper());
+
+ @Override
+ public void execute(Runnable r) {
+ handler.post(r);
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/oauth/api/AccessTokenManager.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.oauth.api;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import static com.baidu.duer.dcs.oauth.api.OauthPreferenceUtil.BAIDU_OAUTH_CONFIG;
+
+/**
+ * 对Token相关信息的管理类,包括初始化、存储、清除相应的token信息
+ * 由于AccessTokenManager涉及到在多个Activity中传递的,所以实现了Parcelable接口
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/24.
+ */
+public class AccessTokenManager implements Parcelable {
+ // accessToken信息
+ private String accessToken;
+ // token过期时间
+ private long expireTime = 0;
+ // 当前的上下文环境
+ private Context context;
+
+ /**
+ * 构建AccessTokenManager类
+ *
+ * @param context 当前的上下文环境,通常为××Activity.this等
+ */
+ public AccessTokenManager(Context context) {
+ this.context = context;
+ compareWithConfig();
+ }
+
+ /**
+ * 通过Parcel流构建AccessTokenManager,主要用在Parcelable.Creator中
+ *
+ * @param source Parcel 流信息
+ */
+ public AccessTokenManager(Parcel source) {
+ Bundle bundle = Bundle.CREATOR.createFromParcel(source);
+ if (bundle != null) {
+ this.accessToken = bundle.getString(OauthConfig.BundleKey.KEY_ACCESS_TOKEN);
+ this.expireTime = bundle.getLong(OauthConfig.BundleKey.KEY_EXPIRE_TIME);
+ }
+ compareWithConfig();
+ }
+
+ /**
+ * 检查当token信息与配置文件是否保持一致,若不一致则对当前的token信息进行初始化
+ */
+ private void compareWithConfig() {
+ if (this.context == null) {
+ return;
+ }
+
+ /**
+ * 对配置的权限信息进行监控,保持多个AccessTokenManager对象之间的,权限信息一致。
+ */
+ final SharedPreferences sp = this.context.getSharedPreferences(BAIDU_OAUTH_CONFIG, Context.MODE_PRIVATE);
+ sp.registerOnSharedPreferenceChangeListener(new OnSharedPreferenceChangeListener() {
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
+ String acToken = sp.getString(OauthConfig.PrefenenceKey.SP_ACCESS_TOKEN, null);
+ if (accessToken != null && !accessToken.equals(acToken)) {
+ initToken();
+ }
+ }
+ });
+ }
+
+ /**
+ * 从SharedPreference中读取token数据,并初步判断数据的有效性
+ */
+ protected void initToken() {
+ this.accessToken = OauthPreferenceUtil.getAccessToken(context);
+ long expires = OauthPreferenceUtil.getExpires(context);
+ long createTime = OauthPreferenceUtil.getCreateTime(context);
+ long current = System.currentTimeMillis();
+ this.expireTime = createTime + expires;
+ if (expireTime != 0 && expireTime < current) {
+ clearToken();
+ }
+ }
+
+ /**
+ * 清楚SharedPreference中的所有数据
+ */
+ protected void clearToken() {
+ OauthPreferenceUtil.clearAllOauth(context);
+ this.accessToken = null;
+ this.expireTime = 0;
+ }
+
+ /**
+ * 将token信息存储到SharedPreference中
+ *
+ * @param values token信息的key-value形式
+ */
+ protected void storeToken(Bundle values) {
+ if (values == null || values.isEmpty()) {
+ return;
+ }
+ this.accessToken = values.getString("access_token");
+ // expires_in 返回值为秒
+ long expiresIn = Long.parseLong(values.getString("expires_in")) * 1000;
+ this.expireTime = System.currentTimeMillis() + expiresIn;
+ OauthPreferenceUtil.setAccessToken(context, this.accessToken);
+ OauthPreferenceUtil.setCreateTime(context, System.currentTimeMillis());
+ OauthPreferenceUtil.setExpires(context, expiresIn);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ Bundle bundle = new Bundle();
+ if (this.accessToken != null) {
+ bundle.putString(OauthConfig.BundleKey.KEY_ACCESS_TOKEN, this.accessToken);
+ }
+ if (this.expireTime != 0) {
+ bundle.putLong(OauthConfig.BundleKey.KEY_EXPIRE_TIME, this.expireTime);
+ }
+ bundle.writeToParcel(dest, flags);
+ }
+
+ public static final Creator<AccessTokenManager> CREATOR = new Creator<AccessTokenManager>() {
+ @Override
+ public AccessTokenManager createFromParcel(Parcel source) {
+ return new AccessTokenManager(source);
+ }
+
+ @Override
+ public AccessTokenManager[] newArray(int size) {
+ return new AccessTokenManager[size];
+ }
+
+ };
+
+ /**
+ * 判断当前的token信息是否有效
+ *
+ * @return true/false
+ */
+ protected boolean isSessionValid() {
+ if (this.accessToken == null || this.expireTime == 0) {
+ initToken();
+ }
+ return this.accessToken != null && this.expireTime != 0 && System.currentTimeMillis() < this.expireTime;
+ }
+
+ /**
+ * 获取AccessToken信息
+ *
+ * @return accessToken
+ */
+ public String getAccessToken() {
+ if (this.accessToken == null) {
+ initToken();
+ }
+ return this.accessToken;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/oauth/api/BaiduDialog.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.oauth.api;
+
+import android.app.Dialog;
+import android.app.ProgressDialog;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.FrameLayout;
+import android.widget.RelativeLayout;
+
+import com.baidu.duer.dcs.androidsystemimpl.webview.BaseWebView;
+import com.baidu.duer.dcs.util.LogUtil;
+
+/**
+ * 自定义的Dialog UI类,用来展示WebView界面,即用户登录和授权的页面
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/24.
+ */
+public class BaiduDialog extends Dialog {
+ private static final FrameLayout.LayoutParams MATCH = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT);
+ private static final String LOG_TAG = "BaiduDialog";
+ private final String mUrl;
+ private final BaiduDialogListener mListener;
+ private ProgressDialog mSpinner;
+ private BaseWebView mWebView;
+ private FrameLayout mContent;
+ private RelativeLayout webViewContainer;
+
+ /**
+ * 构造BaiduDialog
+ *
+ * @param context 展示Dialog UI的上下文环境,通常是XXActivity.this
+ * @param url 用户请求的url地址
+ * @param listener 用于对请求回调的Listener对象
+ */
+ public BaiduDialog(Context context, String url, BaiduDialogListener listener) {
+ super(context, android.R.style.Theme_Translucent_NoTitleBar);
+ mUrl = url;
+ mListener = listener;
+ }
+
+ @Override
+ public boolean onKeyDown(int keyCode, KeyEvent event) {
+ mListener.onCancel();
+ return super.onKeyDown(keyCode, event);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // 设置ProgressDialog的样式
+ mSpinner = new ProgressDialog(getContext());
+ mSpinner.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ mSpinner.setMessage("登录中...");
+ requestWindowFeature(Window.FEATURE_NO_TITLE);
+ mContent = new FrameLayout(getContext());
+ setUpWebView();
+ addContentView(mContent, MATCH);
+ }
+
+ private void setUpWebView() {
+ webViewContainer = new RelativeLayout(getContext());
+ mWebView = new BaseWebView(getContext().getApplicationContext());
+ mWebView.setWebViewClient(new BdWebViewClient());
+ mWebView.loadUrl(mUrl);
+ mWebView.setLayoutParams(MATCH);
+ mWebView.setVisibility(View.INVISIBLE);
+ webViewContainer.addView(mWebView);
+ mContent.addView(webViewContainer, MATCH);
+ }
+
+ private class BdWebViewClient extends WebViewClient {
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ LogUtil.d(LOG_TAG, "Redirect URL: " + url);
+ /*
+ * 如果url的地址为bdconnect://success,即使用User-Agent方式获取用户授权的redirct
+ * url,则截取url中返回的各种token参数,
+ * 如果出错,则通过listener的相应处理方式回调
+ */
+ if (url.startsWith(BaiduOauthImplicitGrant.SUCCESS_URI)) {
+ Bundle values = OauthNetUtil.parseUrl(url);
+ if (values != null && !values.isEmpty()) {
+ String error = values.getString("error");
+ // 用户取消授权返回error=access_denied
+ if ("access_denied".equals(error)) {
+ mListener.onCancel();
+ BaiduDialog.this.dismiss();
+ return true;
+ }
+ // 请求出错时返回error=1100&errorDesp=error_desp
+ String errorDesp = values.getString("error_description");
+ if (error != null && errorDesp != null) {
+ mListener.onBaiduException(new BaiduException(error, errorDesp));
+ BaiduDialog.this.dismiss();
+ return true;
+ }
+ mListener.onComplete(values);
+ BaiduDialog.this.dismiss();
+ return true;
+ }
+ } else if (url.startsWith(BaiduOauthImplicitGrant.CANCEL_URI)) {
+ mListener.onCancel();
+ BaiduDialog.this.dismiss();
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public void onReceivedError(WebView view, int errorCode, String description,
+ String failingUrl) {
+ super.onReceivedError(view, errorCode, description, failingUrl);
+ mListener.onError(new BaiduDialogError(description, errorCode, failingUrl));
+ BaiduDialog.this.dismiss();
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ LogUtil.d(LOG_TAG, "Webview loading URL: " + url);
+ super.onPageStarted(view, url, favicon);
+ mSpinner.show();
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ super.onPageFinished(view, url);
+ mSpinner.dismiss();
+ mContent.setBackgroundColor(Color.TRANSPARENT);
+ mWebView.setVisibility(View.VISIBLE);
+ }
+ }
+
+ @Override
+ public void dismiss() {
+ super.dismiss();
+ webViewContainer.removeView(mWebView);
+ mWebView.removeAllViews();
+ mWebView.destroy();
+ }
+
+ /**
+ * 用于BaiduDialog回调接口
+ */
+ public interface BaiduDialogListener {
+ /**
+ * BaiduDailog请求成功时,执行该法方法,实现逻辑包括存储value信息,跳转activity的过程
+ *
+ * @param values token信息的key-value存储
+ */
+ void onComplete(Bundle values);
+
+ /**
+ * 当BaiduDialog执行发生BaiduException时执行的方法。
+ *
+ * @param e BaiduException信息
+ */
+ void onBaiduException(BaiduException e);
+
+ /**
+ * 发生DialogError时执行的方法
+ *
+ * @param e BaiduDialogError异常类
+ */
+ void onError(BaiduDialogError e);
+
+ /**
+ * 当BaiduDialog执行取消操作时,执行该方法
+ */
+ void onCancel();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/oauth/api/BaiduDialogError.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.oauth.api;
+
+/**
+ * 封装Dialog UI的错误异常信息类
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/24.
+ */
+public class BaiduDialogError extends Exception {
+ private static final long serialVersionUID = 1529106452635370329L;
+ private int errorCode;
+ private String failingUrl;
+
+ public BaiduDialogError(String message, int errorCode, String failingUrl) {
+ super(message);
+ this.errorCode = errorCode;
+ this.failingUrl = failingUrl;
+ }
+
+ public int getErrorCode() {
+ return errorCode;
+ }
+
+ public String getFailingUrl() {
+ return failingUrl;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/oauth/api/BaiduException.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.oauth.api;
+
+/**
+ * 封装了oauth授权和api请求的异常信息
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/24.
+ */
+public class BaiduException extends Exception {
+ private static final long serialVersionUID = -8309515227501598366L;
+ private String errorCode;
+ private String errorMsg;
+
+ public BaiduException() {
+ super();
+ }
+
+ public BaiduException(String detailMessage, Throwable throwable) {
+ super(detailMessage, throwable);
+ }
+
+ public BaiduException(String detailMessage) {
+ super(detailMessage);
+ }
+
+ public BaiduException(Throwable throwable) {
+ super(throwable);
+ }
+
+ public BaiduException(String errorCode, String errorDesp) {
+ this.errorCode = errorCode;
+ this.errorMsg = errorDesp;
+ }
+
+ public String getErrorCode() {
+ return errorCode;
+ }
+
+ public void setErrorCode(String errorCode) {
+ this.errorCode = errorCode;
+ }
+
+ public String getErrorDesp() {
+ return errorMsg;
+ }
+
+ public void setErrorDesp(String errorDesp) {
+ this.errorMsg = errorDesp;
+ }
+
+ @Override
+ public String toString() {
+ return "BaiduException [errorCode=" + errorCode + ", errorDesp=" + errorMsg + "]";
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/oauth/api/BaiduOauthImplicitGrant.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,277 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.oauth.api;
+
+import android.Manifest;
+import android.app.Activity;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+import android.webkit.CookieSyncManager;
+
+import com.baidu.duer.dcs.oauth.api.BaiduDialog.BaiduDialogListener;
+import com.baidu.duer.dcs.util.CommonUtil;
+import com.baidu.duer.dcs.util.LogUtil;
+
+/**
+ * 封装了oauth2授权,我们采用的是百度Oauth的implicit grant的方式
+ * 该方式的地址:http://developer.baidu.com/wiki/index.php?title=docs/oauth/implicit
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/24.
+ * TODO: 百度Oauth2授权方式完善
+ */
+public class BaiduOauthImplicitGrant implements Parcelable {
+ private static final String LOG_TAG = "BaiduOauth";
+ public static final String CANCEL_URI = "bdconnect://cancel";
+ // 百度Oauth授权回调需要在DUEROS开放平台的控制平台
+ // 应用编辑-->>OAUTH CONFIG URL的链接地址-->>授权回调页-->>安全设置-->>授权回调页
+ // 需要注意
+ public static final String SUCCESS_URI = "bdconnect://success";
+ private static final String OAUTHORIZE_URL = "https://openapi.baidu.com/oauth/2.0/authorize";
+ private static final String DISPLAY_STRING = "mobile";
+ private static final String[] DEFAULT_PERMISSIONS = {"basic"};
+ private static final String KEY_CLIENT_ID = "clientId";
+ // 应用注册的api key信息
+ private String cliendId;
+ private AccessTokenManager accessTokenManager;
+
+ /**
+ * 使用应用的基本信息构建Baidu对象
+ *
+ * @param clientId 应用注册的api key信息
+ * @param context 当前应用的上下文环境
+ */
+ public BaiduOauthImplicitGrant(String clientId, Context context) {
+ if (clientId == null) {
+ throw new IllegalArgumentException("apiKey信息必须提供!");
+ }
+ this.cliendId = clientId;
+ init(context);
+ }
+
+ /**
+ * 使用Parcel流构建Baidu对象
+ *
+ * @param in Parcel流信息
+ */
+ public BaiduOauthImplicitGrant(Parcel in) {
+ Bundle bundle = Bundle.CREATOR.createFromParcel(in);
+ this.cliendId = bundle.getString(KEY_CLIENT_ID);
+ this.accessTokenManager = AccessTokenManager.CREATOR.createFromParcel(in);
+ }
+
+ /**
+ * 初始化accesTokenManager等信息
+ *
+ * @param context 当前执行的上下文环境
+ */
+ public void init(Context context) {
+ if (context.checkCallingOrSelfPermission(Manifest.permission.ACCESS_NETWORK_STATE)
+ != PackageManager.PERMISSION_GRANTED) {
+ Log.w(LOG_TAG, "App miss permission android.permission.ACCESS_NETWORK_STATE! "
+ + "Some mobile's WebView don't display page!");
+ }
+ this.accessTokenManager = new AccessTokenManager(context);
+ this.accessTokenManager.initToken();
+ }
+
+ /**
+ * 完成登录并获取token信息(User-Agent Flow),该方法使用默认的用户权限
+ *
+ * @param activity 需要展示Dialog UI的Activity
+ * @param isForceLogin 是否强制登录,如果该参数为true的话,会强制用户进行登录。
+ * @param isConfirmLogin 是否确认登录,如果该参数为true的话,如果用户当前为登录状态,
+ * 则会显示用户的登录头像,点击头像后完成登录操作
+ * @param listener Dialog回调接口如Activity跳转
+ */
+ public void authorize(Activity activity,
+ boolean isForceLogin,
+ boolean isConfirmLogin,
+ final BaiduDialogListener listener) {
+ this.authorize(activity, null, isForceLogin, isConfirmLogin, listener);
+ }
+
+ /**
+ * 根据相应的permissions信息,完成登录并获取token信息(User-Agent Flow)
+ *
+ * @param activity 需要展示Dialog UI的Activity
+ * @param permissions 需要获得的授权权限信息
+ * @param isForceLogin 是否强制登录,如果该参数为true的话,会强制用户进行登录。
+ * @param listener 回调的listener接口,如Activity跳转等
+ */
+ private void authorize(Activity activity,
+ String[] permissions,
+ boolean isForceLogin,
+ boolean isConfirmLogin,
+ final BaiduDialogListener listener) {
+ if (this.isSessionValid()) {
+ listener.onComplete(new Bundle());
+ return;
+ }
+
+ // 使用匿名的BaiduDialogListener对listener进行了包装,并进行一些存储token信息和当前登录用户的逻辑,
+ // 外部传进来的listener信息不需要在进行存储相关的逻辑
+ this.authorize(activity,
+ permissions,
+ isForceLogin,
+ isConfirmLogin,
+ new BaiduDialogListener() {
+ @Override
+ public void onError(BaiduDialogError e) {
+ LogUtil.d(LOG_TAG, "DialogError " + e);
+ listener.onError(e);
+ }
+
+ @Override
+ public void onComplete(Bundle values) {
+ // 存储相应的token信息
+ getAccessTokenManager().storeToken(values);
+ // 完成授权操作,使用listener进行回调,eg。跳转到其他的activity
+ listener.onComplete(values);
+ }
+
+ @Override
+ public void onCancel() {
+ LogUtil.d(LOG_TAG, "login cancel");
+ listener.onCancel();
+ }
+
+ @Override
+ public void onBaiduException(BaiduException e) {
+ Log.d(LOG_TAG, "BaiduException : " + e);
+ listener.onBaiduException(e);
+ }
+ }, SUCCESS_URI, "token");
+ }
+
+ /**
+ * 通过Dialog UI展示用户登录、授权页
+ *
+ * @param activity 需要展示Dialog UI的Activity
+ * @param permissions 需要请求的环境
+ * @param listener 用于回调的listener接口方法
+ * @param redirectUrl 回调地址
+ * @param responseType 授权请求的类型
+ */
+ private void authorize(Activity activity,
+ String[] permissions,
+ boolean isForceLogin,
+ boolean isConfirmLogin,
+ final BaiduDialogListener listener,
+ String redirectUrl, String responseType) {
+ CookieSyncManager.createInstance(activity);
+ Bundle params = new Bundle();
+ params.putString("client_id", this.cliendId);
+ params.putString("redirect_uri", redirectUrl);
+ params.putString("response_type", responseType);
+ params.putString("display", DISPLAY_STRING);
+ if (isForceLogin) {
+ params.putString("force_login", "1");
+ }
+ if (isConfirmLogin) {
+ params.putString("confirm_login", "1");
+ }
+ if (permissions == null) {
+ permissions = DEFAULT_PERMISSIONS;
+ }
+ if (permissions != null && permissions.length > 0) {
+ String scope = TextUtils.join(" ", permissions);
+ params.putString("scope", scope);
+ }
+ String url = OAUTHORIZE_URL + "?" + CommonUtil.encodeUrl(params);
+ LogUtil.d(LOG_TAG, "url:" + url);
+ if (activity.checkCallingOrSelfPermission(Manifest.permission.INTERNET)
+ != PackageManager.PERMISSION_GRANTED) {
+ CommonUtil.showAlert(activity, "没有权限", "应用需要访问互联网的权限");
+ } else {
+ new BaiduDialog(activity, url, listener).show();
+ }
+ }
+
+ /**
+ * 将清除存储的token信息
+ */
+ public void clearAccessToken() {
+ if (this.accessTokenManager != null) {
+ this.accessTokenManager.clearToken();
+ this.accessTokenManager = null;
+ }
+ }
+
+ /**
+ * 判断token信息是否有效。
+ *
+ * @return boolean true/false
+ */
+ public boolean isSessionValid() {
+ return this.accessTokenManager.isSessionValid();
+ }
+
+ /**
+ * 获取AccessTokenManager对象
+ *
+ * @return accessTokenManager对象
+ */
+ public AccessTokenManager getAccessTokenManager() {
+ return this.accessTokenManager;
+ }
+
+ /**
+ * 获取AccessToken信息
+ *
+ * @return accessToken信息
+ */
+ public String getAccessToken() {
+ return this.accessTokenManager.getAccessToken();
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see android.os.Parcelable#describeContents()
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see android.os.Parcelable#writeToParcel(android.os.Parcel, int)
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ Bundle bundle = new Bundle();
+ bundle.putString(KEY_CLIENT_ID, this.cliendId);
+ bundle.writeToParcel(dest, flags);
+ this.accessTokenManager.writeToParcel(dest, flags);
+ }
+
+ public static final Creator<BaiduOauthImplicitGrant> CREATOR = new Creator<BaiduOauthImplicitGrant>() {
+ public BaiduOauthImplicitGrant createFromParcel(Parcel in) {
+ return new BaiduOauthImplicitGrant(in);
+ }
+
+ public BaiduOauthImplicitGrant[] newArray(int size) {
+ return new BaiduOauthImplicitGrant[size];
+ }
+ };
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/oauth/api/IOauth.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.oauth.api;
+
+/**
+ * 百度认证接口
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/8.
+ */
+public interface IOauth {
+ /**
+ * 获取accessToken
+ *
+ * @return String
+ */
+ String getAccessToken();
+
+ /**
+ * 用户认证
+ */
+ void authorize();
+
+ /**
+ * 判断当前的token信息是否有效
+ *
+ * @return true/false
+ */
+ boolean isSessionValid();
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/oauth/api/OauthConfig.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.oauth.api;
+
+/**
+ * OauthConfig
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/3.
+ */
+public class OauthConfig {
+ public static class BundleKey {
+ // 在多个Activity中传递AccessTokenManager的键值
+ public static final String KEY_ACCESS_TOKEN = "baidu_token_manager_access_token";
+ public static final String KEY_EXPIRE_TIME = "baidu_token_manager_expire_time";
+ }
+
+ public static class PrefenenceKey {
+ // 持久化token信息的各种监制
+ public static final String SP_ACCESS_TOKEN = "baidu_oauth_config_prop_access_token";
+ public static final String SP_CREATE_TIME = "baidu_oauth_config_prop_create_time";
+ public static final String SP_EXPIRE_SECONDS = "baidu_oauth_config_prop_expire_secends";
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/oauth/api/OauthImpl.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.oauth.api;
+
+import android.content.Intent;
+import android.text.TextUtils;
+
+import com.baidu.duer.dcs.androidapp.DcsSampleApplication;
+import com.baidu.duer.dcs.androidapp.DcsSampleOAuthActivity;
+
+/**
+ * 用户认证接口
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/8.
+ */
+public class OauthImpl implements IOauth {
+ @Override
+ public String getAccessToken() {
+ return OauthPreferenceUtil.getAccessToken(DcsSampleApplication.getInstance());
+ }
+
+ @Override
+ public void authorize() {
+ Intent intent = new Intent(DcsSampleApplication.getInstance(), DcsSampleOAuthActivity.class);
+ intent.putExtra("START_TAG", "RESTART");
+ intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+ DcsSampleApplication.getInstance().startActivity(intent);
+ }
+
+ @Override
+ public boolean isSessionValid() {
+ String accessToken = getAccessToken();
+ long createTime = OauthPreferenceUtil.getCreateTime(DcsSampleApplication.getInstance());
+ long expires = OauthPreferenceUtil.getExpires(DcsSampleApplication.getInstance()) + createTime;
+ return !TextUtils.isEmpty(accessToken) && expires != 0 && System.currentTimeMillis() < expires;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/oauth/api/OauthNetUtil.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.oauth.api;
+
+import android.os.Bundle;
+
+import com.baidu.duer.dcs.util.CommonUtil;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * Util类封装了一些基本的方法
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/19.
+ */
+public class OauthNetUtil {
+ /**
+ * 提取回调url中的token信息,用于User-Agent Flow中的授权操作
+ *
+ * @param url 回调的url,包括token信息
+ * @return 返回bundle类型的token信息
+ */
+ public static Bundle parseUrl(String url) {
+ Bundle ret;
+ url = url.replace("bdconnect", "http");
+ try {
+ URL urlParam = new URL(url);
+ ret = CommonUtil.decodeUrl(urlParam.getQuery());
+ ret.putAll(CommonUtil.decodeUrl(urlParam.getRef()));
+ return ret;
+ } catch (MalformedURLException e) {
+ return new Bundle();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/oauth/api/OauthPreferenceUtil.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.oauth.api;
+
+import android.content.Context;
+
+import com.baidu.duer.dcs.util.PreferenceUtil;
+
+/**
+ * 用户认证保存Preference工具类
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/6/3.
+ */
+public class OauthPreferenceUtil extends PreferenceUtil {
+ public static final String BAIDU_OAUTH_CONFIG = "baidu_oauth_config";
+
+ /**
+ * 保存数据的方法,拿到保存数据的具体类型,然后根据类型调用不同的保存方法
+ *
+ * @param context 上下文
+ * @param key key
+ * @param object value
+ */
+ public static void put(Context context, String key, Object object) {
+ put(context, BAIDU_OAUTH_CONFIG, key, object);
+ }
+
+ /**
+ * 得到保存数据的方法,
+ * 根据默认值得到保存的数据的具体类型,
+ * 然后调用相对于的方法获取值
+ *
+ * @param context 上下文
+ * @param key key
+ * @param defaultObject default-value
+ */
+ public static Object get(Context context, String key, Object defaultObject) {
+ return get(context, BAIDU_OAUTH_CONFIG, key, defaultObject);
+ }
+
+ public static void clear(Context context) {
+ clear(context, BAIDU_OAUTH_CONFIG);
+ }
+
+ public static void setAccessToken(Context context, String value) {
+ put(context, OauthConfig.PrefenenceKey.SP_ACCESS_TOKEN, value);
+ }
+
+ public static String getAccessToken(Context context) {
+ return (String) get(context, OauthConfig.PrefenenceKey.SP_ACCESS_TOKEN, "");
+ }
+
+ public static void setExpires(Context context, long value) {
+ put(context, OauthConfig.PrefenenceKey.SP_EXPIRE_SECONDS, value);
+ }
+
+ public static long getExpires(Context context) {
+ return (long) get(context, OauthConfig.PrefenenceKey.SP_EXPIRE_SECONDS, 0L);
+ }
+
+ public static void setCreateTime(Context context, long value) {
+ put(context, OauthConfig.PrefenenceKey.SP_CREATE_TIME, value);
+ }
+
+ public static long getCreateTime(Context context) {
+ return (long) get(context, OauthConfig.PrefenenceKey.SP_CREATE_TIME, 0L);
+ }
+
+ public static void clearAllOauth(Context context) {
+ clear(context);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/systeminterface/IAlertsDataStore.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.systeminterface;
+
+import com.baidu.duer.dcs.devicemodule.alerts.message.Alert;
+
+import java.util.List;
+
+/**
+ * alert存储的回调接口
+ *
+ * Created by guxiuzhong@baidu.com on 2017/5/18.
+ */
+public interface IAlertsDataStore {
+
+ void readFromDisk(ReadResultListener listener);
+
+ void writeToDisk(List<Alert> alerts, WriteResultListener listener);
+
+ /**
+ * 读取回调
+ */
+ interface ReadResultListener {
+ void onSucceed(List<Alert> alerts);
+
+ void onFailed(String errMsg);
+ }
+
+ /**
+ * 写入回调
+ */
+ interface WriteResultListener {
+ void onSucceed();
+
+ void onFailed(String errMsg);
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/systeminterface/IAudioInput.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.systeminterface;
+
+import com.baidu.duer.dcs.framework.message.DcsStreamRequestBody;
+
+/**
+ * 语音输入接口
+ * <p>
+ * Created by wuruisheng on 2017/5/31.
+ */
+public interface IAudioInput {
+ /**
+ * 处理开始录音的逻辑
+ */
+ void startRecord();
+
+ /**
+ * 处理停止录音的逻辑
+ */
+ void stopRecord();
+
+ void registerAudioInputListener(IAudioInputListener audioInputListener);
+
+ interface IAudioInputListener {
+ void onStartRecord(DcsStreamRequestBody dcsStreamRequestBody);
+ void onStopRecord();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/systeminterface/IAudioRecord.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,34 @@
+/*
+ * *
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.systeminterface;
+
+/**
+ * 录音采集接口
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/26.
+ */
+public interface IAudioRecord {
+ /**
+ * 开始录音,采集音频数据
+ */
+ void startRecord();
+
+ /**
+ * 停止录音
+ */
+ void stopRecord();
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/systeminterface/IHandler.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.systeminterface;
+
+/**
+ * handler接口
+ * <p>
+ * Created by wuruisheng on 2017/6/7.
+ */
+public interface IHandler {
+ boolean post(Runnable runnable);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/systeminterface/IMediaPlayer.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.systeminterface;
+
+import java.io.InputStream;
+
+/**
+ * 播放器接口
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/31.
+ */
+public interface IMediaPlayer {
+ /**
+ * 播放状态
+ */
+ enum PlayState {
+ ERROR(-1), // 播放错误
+ IDLE(0), // 播放未开始
+ PREPARING(1), // 播放准备中
+ PREPARED(2), // 播放准备就绪
+ PLAYING(3), // 正在播放
+ PAUSED(4), // 暂停播放
+ STOPPED(5), // 停止状态
+ COMPLETED(6); // 播放完成
+
+ private int state;
+
+ PlayState(int state) {
+ this.state = state;
+ }
+
+ public int getState() {
+ return state;
+ }
+ }
+
+ /**
+ * 获取当前的播放状态
+ *
+ * @return PlayState
+ */
+ PlayState getPlayState();
+
+ /**
+ * 播放
+ *
+ * @param mediaResource mediaResource
+ */
+ void play(MediaResource mediaResource);
+
+ /**
+ * 暂停
+ */
+ void pause();
+
+ /**
+ * 停止播放
+ */
+ void stop();
+
+ /**
+ * 调用pause暂停后重新播放
+ */
+ void resume();
+
+ /**
+ * 从milliseconds位置开始播放
+ *
+ * @param milliseconds 毫秒
+ */
+ void seekTo(int milliseconds);
+
+ /**
+ * 释放,销毁播放器
+ */
+ void release();
+
+ /**
+ * 设置音量 volume:0-1
+ *
+ * @param volume 音量(0-1之间的浮点数)
+ */
+ void setVolume(float volume);
+
+ float getVolume();
+
+ /**
+ * 设置静音
+ *
+ * @param mute 静音开关
+ */
+ void setMute(boolean mute);
+
+ boolean getMute();
+
+ /**
+ * 获取当前的播放位置
+ *
+ * @return 当前的播放位置
+ */
+ long getCurrentPosition();
+
+ /**
+ * 获取当前音频文件/流的总时长,单位:ms
+ *
+ * @return ms
+ */
+ long getDuration();
+
+ /**
+ * 获取当前缓冲到多少 0-100f
+ *
+ * @return 0-100f
+ */
+ float getBufferPercentage();
+
+ /**
+ * 添加播放器状态回调
+ *
+ * @param listener listener
+ */
+ void addMediaPlayerListener(IMediaPlayerListener listener);
+
+ void removeMediaPlayerListener(IMediaPlayerListener listener);
+
+ /**
+ * 设置播放通道是否处在活跃状态,比如:当用户在语音请求时,对话通道进入活跃状态
+ *
+ * @param isActive 是否处在活跃状态
+ */
+ void setActive(boolean isActive);
+
+ boolean isActive();
+
+ /**
+ * 播放器播放状态回调接口
+ */
+ interface IMediaPlayerListener {
+
+ /**
+ * 调用完play方法后回调此方法
+ */
+ void onInit();
+
+ /**
+ * 播放器准备完成后回调
+ */
+ void onPrepared();
+
+ /**
+ * 播放器销毁后回调
+ */
+ void onRelease();
+
+ /**
+ * 正在播放时回调
+ */
+ void onPlaying();
+
+ /**
+ * 暂停后回调
+ */
+ void onPaused();
+
+ void onStopped();
+
+ /**
+ * 播放完成后回调
+ */
+ void onCompletion();
+
+ /**
+ * 播放出错
+ */
+ void onError(String error, ErrorType errorType);
+
+ /**
+ * 播放器缓冲回调
+ *
+ * @param percent 缓冲的进度 0-100
+ */
+ void onBufferingUpdate(int percent);
+
+ /**
+ * 开始缓冲时回调
+ */
+ void onBufferingStart();
+
+ /**
+ * 结束缓冲时回调
+ */
+ void onBufferingEnd();
+
+ }
+
+ /**
+ * 播放错误类型信息
+ */
+ enum ErrorType {
+ MEDIA_ERROR_UNKNOWN("An unknown error occurred"),
+ MEDIA_ERROR_INVALID_REQUEST(
+ "The server recognized the request as being malformed "
+ + "(bad request, unauthorized, forbidden, not found, etc)"),
+ MEDIA_ERROR_SERVICE_UNAVAILABLE("The device was unavailable to reach the service"),
+ MEDIA_ERROR_INTERNAL_SERVER_ERROR(
+ "The server accepted the request, but was unable to process it as expected"),
+ MEDIA_ERROR_INTERNAL_DEVICE_ERROR("There was an internal error on the device");
+
+ private final String message;
+
+ ErrorType(String message) {
+ this.message = message;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+ }
+
+ /**
+ * 内部空实现的IMediaPlayerListener,如果你只关心onCompletion,可以用这个
+ */
+ class SimpleMediaPlayerListener implements IMediaPlayerListener {
+ @Override
+ public void onInit() {
+
+ }
+
+ @Override
+ public void onPrepared() {
+
+ }
+
+ @Override
+ public void onRelease() {
+
+ }
+
+ @Override
+ public void onPlaying() {
+
+ }
+
+ @Override
+ public void onPaused() {
+
+ }
+
+ @Override
+ public void onStopped() {
+
+ }
+
+ @Override
+ public void onCompletion() {
+
+ }
+
+ @Override
+ public void onError(String error, ErrorType errorType) {
+
+ }
+
+ @Override
+ public void onBufferingUpdate(int percent) {
+
+ }
+
+ @Override
+ public void onBufferingStart() {
+
+ }
+
+ @Override
+ public void onBufferingEnd() {
+
+ }
+ }
+
+ /**
+ * 需要播放的音频类型
+ */
+ final class MediaResource {
+ public InputStream stream; // 流类型
+ public String url; // url类型
+ public boolean isStream; // 是否值流类型
+
+ public MediaResource(InputStream stream) {
+ this.stream = stream;
+ this.isStream = true;
+ }
+
+ public MediaResource(String url) {
+ this.url = url;
+ this.isStream = false;
+ }
+
+ @Override
+ public String toString() {
+ if (isStream) {
+ return "stream";
+ } else {
+ return url;
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/systeminterface/IPlatformFactory.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.systeminterface;
+
+/**
+ * 定义平台相关工厂类
+ *
+ * Created by wuruisheng on 2017/6/7.
+ */
+public interface IPlatformFactory {
+ IHandler createHandler();
+ IHandler getMainHandler();
+ IAudioRecord getAudioRecord();
+ IWakeUp getWakeUp();
+ IAudioInput getVoiceInput();
+ IMediaPlayer createMediaPlayer();
+ IAlertsDataStore createAlertsDataStore();
+ IWebView getWebView();
+ void setWebView(IWebView webView);
+ IPlaybackController getPlayback();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/systeminterface/IPlaybackController.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.systeminterface;
+
+import com.baidu.duer.dcs.framework.IResponseListener;
+
+/**
+ * PlaybackController接口
+ * <p>
+ * Created by zhoujianliang01 on 2017/6/17.
+ */
+public interface IPlaybackController {
+ void play(IResponseListener responseListener);
+
+ void pause(IResponseListener responseListener);
+
+ void previous(IResponseListener responseListener);
+
+ void next(IResponseListener responseListener);
+
+ void registerPlaybackListener(IPlaybackListener listener);
+
+ interface IPlaybackListener {
+ void onPlay(IResponseListener responseListener);
+
+ void onPause(IResponseListener responseListener);
+
+ void onPrevious(IResponseListener responseListener);
+
+ void onNext(IResponseListener responseListener);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/systeminterface/IWakeUp.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,58 @@
+/*
+ * *
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.systeminterface;
+
+/**
+ * 唤醒接口
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/25.
+ */
+public interface IWakeUp {
+ /**
+ * 开始唤醒
+ * 1.初始化唤醒词
+ * 2.打开麦克风,并开始音频唤醒的解码
+ */
+ void startWakeUp();
+
+ /**
+ * 停止唤醒,调用停止录音
+ */
+ void stopWakeUp();
+
+ /**
+ * 释放资源,比如调用底层库释放资源等
+ */
+ void releaseWakeUp();
+
+ /**
+ * 唤醒结果的回调监听
+ *
+ * @param listener 监听实现
+ */
+ void addWakeUpListener(IWakeUpListener listener);
+
+ /**
+ * 唤醒结果的回调接口
+ */
+ interface IWakeUpListener {
+ /**
+ * 唤醒成功后回调
+ */
+ void onWakeUpSucceed();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/systeminterface/IWebView.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.systeminterface;
+
+/**
+ * WebView接口
+ * <p>
+ * Created by zhoujianliang01 on 2017/6/17.
+ */
+public interface IWebView {
+ void loadUrl(String url);
+ void linkClicked(String url);
+
+ void addWebViewListener(IWebViewListener listener);
+
+ interface IWebViewListener {
+ void onLinkClicked(String url);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/util/CommonUtil.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.util;
+
+import android.app.AlertDialog;
+import android.app.AlertDialog.Builder;
+import android.content.Context;
+import android.os.Build;
+import android.os.Bundle;
+import android.text.TextUtils;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.UUID;
+
+/**
+ * 辅助工具类
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/17.
+ */
+public class CommonUtil {
+ private static final int JSON_INDENT = 4;
+
+ public static String getCurrentTime() {
+ SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
+ Locale.CHINESE);
+ return format.format(new Date());
+ }
+
+ /**
+ * 将毫秒格式转化为yyyy-MM-dd HH:mm:ss
+ *
+ * @param milliSeconds 毫秒
+ * @return 格式化后的字符串结果
+ */
+ public static String formatToDataTime(long milliSeconds) {
+ SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
+ return sd.format(milliSeconds);
+ }
+
+ /**
+ * 将key1=value1&key2=value2格式的query转换成key-value形式的参数串
+ *
+ * @param query key1=value1&key2=value2格式的query
+ * @return key-value形式的bundle
+ */
+ public static Bundle decodeUrl(String query) {
+ Bundle ret = new Bundle();
+ if (query != null) {
+ String[] pairs = query.split("&");
+ for (String pair : pairs) {
+ String[] keyAndValues = pair.split("=");
+ if (keyAndValues != null && keyAndValues.length == 2) {
+ String key = keyAndValues[0];
+ String value = keyAndValues[1];
+ if (!TextUtils.isEmpty(key) && !TextUtils.isEmpty(value)) {
+ ret.putString(URLDecoder.decode(key), URLDecoder.decode(value));
+ }
+ }
+ }
+ }
+ return ret;
+ }
+
+ /**
+ * 将key-value形式的参数串,转换成key1=value1&key2=value2格式的query
+ *
+ * @param params key-value参数
+ * @return key1=value1&key2=value2格式的query
+ */
+ public static String encodeUrl(Bundle params) {
+ if (params == null || params.isEmpty()) {
+ return null;
+ }
+ boolean first = true;
+ StringBuilder sb = new StringBuilder();
+ for (String key : params.keySet()) {
+ String paramValue = params.getString(key);
+ if (paramValue == null) {
+ continue;
+ }
+ if (first) {
+ first = false;
+ } else {
+ sb.append("&");
+ }
+ sb.append(URLEncoder.encode(key)).append("=").append(URLEncoder.encode(paramValue));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * 展示一个通用的弹出框UI
+ *
+ * @param context 展示弹出框的上下文环境
+ * @param title 警告的title信息
+ * @param text 警告信息
+ */
+ public static void showAlert(Context context, String title, String text) {
+ AlertDialog alertDialog = new Builder(context).create();
+ alertDialog.setTitle(title);
+ alertDialog.setMessage(text);
+ alertDialog.setCanceledOnTouchOutside(true);
+ alertDialog.show();
+ }
+
+ private static long lastClickTime;
+
+ /**
+ * 是否是双击
+ *
+ * @return true 是,false 否
+ */
+ public static boolean isFastDoubleClick() {
+ long time = System.currentTimeMillis();
+ if (time - lastClickTime < 500) {
+ return true;
+ }
+ lastClickTime = time;
+ return false;
+ }
+
+ /**
+ * json 格式化输出
+ *
+ * @param json json字符串
+ * @return 用四个空格缩进后的json字符串结果
+ */
+ public static String formatJson(String json) {
+ String formatted = "";
+ if (json == null || json.length() == 0) {
+ return formatted;
+ }
+ try {
+ if (json.startsWith("{")) {
+ JSONObject jo = new JSONObject(json);
+ formatted = jo.toString(JSON_INDENT);
+ } else if (json.startsWith("[")) {
+ JSONArray ja = new JSONArray(json);
+ formatted = ja.toString(JSON_INDENT);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return formatted;
+ }
+
+ /**
+ * 关闭流
+ *
+ * @param closeables closeables
+ */
+ public static void closeQuietly(Closeable... closeables) {
+ for (Closeable c : closeables) {
+ try {
+ if (c != null) {
+ c.close();
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Android设备物理唯一标识符
+ *
+ * @return String 设备唯一标识
+ */
+ public static String getDeviceUniqueID() {
+ String devIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ devIDShort += (Build.SUPPORTED_ABIS[0].length() % 10);
+ } else {
+ devIDShort += (Build.CPU_ABI.length() % 10);
+ }
+ devIDShort += (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10)
+ + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10);
+ String serial;
+ try {
+ serial = Build.class.getField("SERIAL").get(null).toString();
+ return new UUID(devIDShort.hashCode(), serial.hashCode()).toString();
+ } catch (Exception e) {
+ serial = "Dueros000";
+ }
+ return new UUID(devIDShort.hashCode(), serial.hashCode()).toString();
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/util/DateFormatterUtil.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.util;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+
+/**
+ * iso8601string 时间格式转换
+ * <p>
+ * Created by zhoujianliang01@baidu.com on 2017/6/5.
+ */
+public class DateFormatterUtil {
+ private static final String TAG = "ISO8601DateFormatter";
+ private static final DateFormat DATE_FORMAT_1 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ", Locale.CHINESE);
+ private static final DateFormat DATE_FORMAT_2 = new SimpleDateFormat("yyyy-MM-dd'T'HHmmssZ", Locale.CHINESE);
+ private static final String UTC_PLUS = "+";
+ private static final String UTC_MINUS = "-";
+
+ /**
+ * 将iso8601string格式字符串时间转为Date
+ *
+ * @param iso8601string iso8601格式的时间字符串
+ * @return Date Date类型表示的结果
+ * @throws ParseException ParseException
+ */
+ public static Date toDate(String iso8601string) throws ParseException {
+ iso8601string = iso8601string.trim();
+ if (iso8601string.toUpperCase().indexOf("Z") > 0) {
+ iso8601string = iso8601string.toUpperCase().replace("Z", "+0000");
+ } else if (((iso8601string.indexOf(UTC_PLUS)) > 0)) {
+ iso8601string = replaceColon(iso8601string, iso8601string.indexOf(UTC_PLUS));
+ iso8601string = appendZeros(iso8601string, iso8601string.indexOf(UTC_PLUS), UTC_PLUS);
+ } else if (((iso8601string.indexOf(UTC_MINUS)) > 0)) {
+ iso8601string = replaceColon(iso8601string, iso8601string.indexOf(UTC_MINUS));
+ iso8601string = appendZeros(iso8601string, iso8601string.indexOf(UTC_MINUS), UTC_MINUS);
+ }
+ LogUtil.d(TAG, "iso8601string:" + iso8601string);
+ Date date;
+ if (iso8601string.contains(":")) {
+ date = DATE_FORMAT_1.parse(iso8601string);
+ } else {
+ date = DATE_FORMAT_2.parse(iso8601string);
+ }
+ return date;
+ }
+
+ public static String toISO8601String(Date date) {
+ return DATE_FORMAT_1.format(date);
+ }
+
+ private static String replaceColon(String sourceStr, int offsetIndex) {
+ if (sourceStr.substring(offsetIndex).contains(":")) {
+ return sourceStr.substring(0, offsetIndex) + sourceStr.substring(offsetIndex).replace(":", "");
+ }
+ return sourceStr;
+ }
+
+ private static String appendZeros(String sourceStr, int offsetIndex, String offsetChar) {
+ if ((sourceStr.length() - 1) - sourceStr.indexOf(offsetChar, offsetIndex) <= 2) {
+ return sourceStr + "00";
+ }
+ return sourceStr;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/util/FileUtil.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.util;
+
+import android.os.Environment;
+import android.text.TextUtils;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+
+/**
+ * FileUtil
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/31.
+ */
+public class FileUtil {
+ public static final String TEMP_POSTFIX = ".download";
+ private static final String LOG_FILE = "LogAll.txt";
+ private static final String APP_DIR = "/DCS";
+ private static final String SPEAK = APP_DIR + "/Speak";
+ private static final String ALERT = APP_DIR + "/Alert";
+ private static final String ALARM_FILE = "alarms.json";
+
+ private static String getSpeakDirPath() {
+ String dirPath = "";
+ if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + SPEAK;
+ File dir = new File(dirPath);
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+ }
+ return dirPath;
+ }
+
+ private static String getAlertDirPath() {
+ String dirPath = "";
+ if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+ dirPath = Environment.getExternalStorageDirectory().getAbsolutePath() + ALERT;
+ File dir = new File(dirPath);
+ if (!dir.exists()) {
+ dir.mkdirs();
+ }
+ }
+ return dirPath;
+ }
+
+ public static File getSpeakFile() {
+ String dirPath = getSpeakDirPath();
+ if (TextUtils.isEmpty(dirPath)) {
+ return null;
+ }
+ return new File(dirPath,
+ "dcs_" + System.currentTimeMillis() + ".mp3" + TEMP_POSTFIX);
+ }
+
+ public static File getAlarmFile() {
+ String dirPath = getAlertDirPath();
+ if (TextUtils.isEmpty(dirPath)) {
+ return null;
+ }
+ return new File(dirPath, ALARM_FILE);
+ }
+
+ public static String getLogFilePath() {
+ return Environment.getExternalStorageDirectory().getAbsolutePath()
+ + APP_DIR + File.separator + LOG_FILE;
+ }
+
+ /**
+ * 日志追加文件
+ *
+ * @param content 追加的内容
+ */
+ public static void appendStrToFile(String content) {
+ File file = new File(getLogFilePath());
+ if (!file.isFile()) {
+ file.delete();
+ }
+ if (!file.exists()) {
+ try {
+ file.createNewFile();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ BufferedWriter out = null;
+ try {
+ out = new BufferedWriter(new OutputStreamWriter(
+ new FileOutputStream(file, true)));
+ out.write(content);
+ out.flush();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ try {
+ out.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/util/LogUtil.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.util;
+
+import android.util.Log;
+
+/**
+ * Log日志输出信息
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/24.
+ */
+public class LogUtil {
+ // 是否开始debug模式,日志输出
+ public static boolean DEBUG = true;
+ private static final String APPNAME = "DCS-";
+ private static boolean LOGV_ON = DEBUG;
+ private static boolean LOGD_ON = DEBUG;
+ private static boolean LOGI_ON = DEBUG;
+ private static boolean LOGW_ON = DEBUG;
+ private static boolean LOGE_ON = DEBUG;
+ // 是否log写文件
+ private static boolean isWriteFile = true;
+
+ /**
+ * 设置debug 开关
+ *
+ * @param isDebug debug开关,true为开,false为关
+ */
+ public static void setDEBUG(boolean isDebug) {
+ DEBUG = isDebug;
+ LOGV_ON = true & DEBUG;
+ LOGD_ON = true & DEBUG;
+ LOGI_ON = true & DEBUG;
+ LOGW_ON = true & DEBUG;
+ LOGE_ON = true & DEBUG;
+ }
+
+ public static boolean getDEBUG() {
+ return DEBUG;
+ }
+
+ /**
+ * 记录相应的log信息v
+ *
+ * @param tag log tag 信息
+ * @param msg log msg 信息
+ */
+ public static void v(String tag, String msg) {
+ if (LOGV_ON) {
+ tag = APPNAME + tag;
+ Log.v(tag, msg);
+ writeLog("V", tag, msg, null);
+ }
+ }
+
+ public static void v(Class<?> c, String msg) {
+ if (LOGV_ON) {
+ String tag = APPNAME + c.getSimpleName();
+ Log.v(tag, msg);
+ writeLog("V", tag, msg, null);
+ }
+ }
+
+ public static void d(Class<?> c, String msg) {
+ if (LOGD_ON) {
+ String tag = APPNAME + c.getSimpleName();
+ Log.d(tag, msg);
+ writeLog("D", tag, msg, null);
+ }
+ }
+
+ /**
+ * 记录相应的log信息d
+ *
+ * @param tag log tag 信息
+ * @param msg log msg 信息
+ */
+ public static void d(String tag, String msg) {
+ if (LOGD_ON) {
+ tag = APPNAME + tag;
+ Log.d(tag, msg);
+ writeLog("D", tag, msg, null);
+ }
+ }
+
+ public static void d(String tag, String msg, Throwable tr) {
+ if (LOGE_ON) {
+ tag = APPNAME + tag;
+ Log.d(tag, msg, tr);
+ writeLog("D", tag, msg, tr);
+ }
+ }
+
+ /**
+ * 记录相应的log信息i
+ *
+ * @param tag log tag 信息
+ * @param msg log msg 信息
+ */
+ public static void i(String tag, String msg) {
+ if (LOGI_ON) {
+ tag = APPNAME + tag;
+ Log.i(tag, msg);
+ writeLog("I", tag, msg, null);
+ }
+ }
+
+ public static void i(Class<?> c, String msg) {
+ if (LOGI_ON) {
+ String tag = APPNAME + c.getSimpleName();
+ Log.i(tag, msg);
+ writeLog("I", tag, msg, null);
+ }
+ }
+
+ public static void w(Class<?> c, String msg) {
+ if (LOGW_ON) {
+ String tag = APPNAME + c.getSimpleName();
+ Log.w(tag, msg);
+ writeLog("W", tag, msg, null);
+ }
+ }
+
+ public static void w(Class<?> c, String msg, Throwable tr) {
+ if (LOGW_ON) {
+ String tag = APPNAME + c.getSimpleName();
+ Log.w(tag, msg, tr);
+ writeLog("W", tag, msg, tr);
+ }
+ }
+
+ /**
+ * 记录相应的log信息w
+ *
+ * @param tag log tag 信息
+ * @param msg log msg 信息
+ */
+ public static void w(String tag, String msg) {
+ if (LOGW_ON) {
+ tag = APPNAME + tag;
+ Log.w(tag, msg);
+ writeLog("W", tag, msg, null);
+ }
+ }
+
+ public static void w(String tag, String msg, Throwable tr) {
+ if (LOGW_ON) {
+ tag = APPNAME + tag;
+ Log.w(tag, msg, tr);
+ writeLog("W", tag, msg, tr);
+ }
+ }
+
+ /**
+ * 记录相应的log信息e
+ *
+ * @param tag log tag 信息
+ * @param msg log msg 信息
+ */
+ public static void e(String tag, String msg) {
+ if (LOGE_ON) {
+ tag = APPNAME + tag;
+ Log.e(tag, msg);
+ writeLog("E", tag, msg, null);
+ }
+ }
+
+ public static void e(Class<?> c, String msg) {
+ if (LOGE_ON) {
+ String tag = APPNAME + c.getSimpleName();
+ Log.e(tag, msg);
+ writeLog("E", tag, msg, null);
+ }
+ }
+
+ public static void e(String tag, String msg, Throwable tr) {
+ if (LOGE_ON) {
+ tag = APPNAME + tag;
+ Log.e(tag, msg, tr);
+ writeLog("E", tag, msg, tr);
+ }
+ }
+
+ public static void e(Class<?> c, String msg, Throwable tr) {
+ if (LOGE_ON) {
+ String tag = APPNAME + c.getSimpleName();
+ Log.e(tag, msg, tr);
+ writeLog("E", tag, msg, tr);
+ }
+ }
+
+ public static void setIsWriteFile(boolean isWriteFile) {
+ LogUtil.isWriteFile = isWriteFile;
+ }
+
+ private static void writeLog(String logLev, String tag, String msg, Throwable tr) {
+ if (isWriteFile) {
+ try {
+ StringBuffer stringBuffer = new StringBuffer();
+ stringBuffer
+ .append(CommonUtil.getCurrentTime())
+ .append("\n")
+ .append(tag)
+ .append("-")
+ .append(msg);
+ if (tr != null) {
+ stringBuffer.append(Log.getStackTraceString(tr));
+ }
+ stringBuffer.append("\n");
+ // 写文件
+ FileUtil.appendStrToFile(stringBuffer.toString());
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/util/NetWorkUtil.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.util;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.NetworkInfo;
+
+/**
+ * 网络检测工具类
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/5/23.
+ */
+public class NetWorkUtil {
+ public static boolean isNetworkConnected(Context context) {
+ if (context != null) {
+ ConnectivityManager mConnectivityManager = (ConnectivityManager) context
+ .getSystemService(Context.CONNECTIVITY_SERVICE);
+ NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
+ if (mNetworkInfo != null) {
+ return mNetworkInfo.isAvailable();
+ }
+ }
+ return false;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/util/ObjectMapperUtil.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.util;
+
+import org.codehaus.jackson.map.DeserializationConfig;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.codehaus.jackson.map.ObjectReader;
+import org.codehaus.jackson.map.ObjectWriter;
+import org.codehaus.jackson.map.SerializationConfig;
+
+import java.io.IOException;
+
+/**
+ * json序列化成对象和反序列化
+ *
+ * Created by wuruisheng on 2017/5/15.
+ */
+public class ObjectMapperUtil {
+ private static ObjectMapper objectMapper;
+
+ private static class ObjectMapperFactoryHolder {
+ private static final ObjectMapperUtil instance = new ObjectMapperUtil();
+ }
+
+ public static ObjectMapperUtil instance() {
+ return ObjectMapperFactoryHolder.instance;
+ }
+
+ private ObjectMapperUtil() {
+ objectMapper = new ObjectMapper();
+ objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+ objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);
+ objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);
+ }
+
+ public ObjectReader getObjectReader() {
+ return objectMapper.reader();
+ }
+
+ public ObjectReader getObjectReader(Class<?> clazz) {
+ return objectMapper.reader().withType(clazz);
+ }
+
+ public ObjectWriter getObjectWriter() {
+ return objectMapper.writer();
+ }
+
+
+ public String objectToJson(Object obj) {
+ String result = "";
+ try {
+ result = getObjectWriter().writeValueAsString(obj);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return result;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/util/PreferenceUtil.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.util;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.Build;
+
+import java.util.Map;
+
+/**
+ * 提供统一的Preference util方法
+ * <p>
+ * Created by zhangyan42@baidu.com on 2017/5/24.
+ */
+public class PreferenceUtil {
+ private static final String APP_SHARD = "com.baidu.duer.dcs";
+
+ /**
+ * 保存数据的方法,拿到保存数据的具体类型,然后根据类型调用不同的保存方法
+ *
+ * @param context 上下文
+ * @param key key
+ * @param object value
+ */
+ public static void put(Context context, String key, Object object) {
+ put(context, APP_SHARD, key, object);
+ }
+
+ public static void put(Context context, String spName, String key, Object object) {
+ SharedPreferences sp = context.getSharedPreferences(spName,
+ Context.MODE_PRIVATE);
+ Editor editor = sp.edit();
+
+ if (object instanceof String) {
+ editor.putString(key, (String) object);
+ } else if (object instanceof Integer) {
+ editor.putInt(key, (Integer) object);
+ } else if (object instanceof Boolean) {
+ editor.putBoolean(key, (Boolean) object);
+ } else if (object instanceof Float) {
+ editor.putFloat(key, (Float) object);
+ } else if (object instanceof Long) {
+ editor.putLong(key, (Long) object);
+ } else {
+ editor.putString(key, object.toString());
+ }
+ editSubmit(editor);
+ }
+
+ private static void editSubmit(Editor editor) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
+ editor.apply();
+ } else {
+ editor.commit();
+ }
+ }
+
+ /**
+ * 得到保存数据的方法,
+ * 根据默认值得到保存的数据的具体类型,
+ * 然后调用相对于的方法获取值
+ *
+ * @param context 上下文
+ * @param key key
+ * @param defaultObject default-value
+ */
+ public static Object get(Context context, String key, Object defaultObject) {
+ return get(context, APP_SHARD, key, defaultObject);
+ }
+
+ public static Object get(Context context, String spName, String key, Object defaultObject) {
+ SharedPreferences sp = context.getSharedPreferences(spName,
+ Context.MODE_PRIVATE);
+
+ if (defaultObject instanceof String) {
+ return sp.getString(key, (String) defaultObject);
+ } else if (defaultObject instanceof Integer) {
+ return sp.getInt(key, (Integer) defaultObject);
+ } else if (defaultObject instanceof Boolean) {
+ return sp.getBoolean(key, (Boolean) defaultObject);
+ } else if (defaultObject instanceof Float) {
+ return sp.getFloat(key, (Float) defaultObject);
+ } else if (defaultObject instanceof Long) {
+ return sp.getLong(key, (Long) defaultObject);
+ }
+ return null;
+ }
+
+ /**
+ * 移除某个key值已经对应的值
+ *
+ * @param context 上下文
+ * @param key key
+ */
+ public static void remove(Context context, String key) {
+ remove(context, APP_SHARD, key);
+ }
+
+ public static void remove(Context context, String spName, String key) {
+ SharedPreferences sp = context.getSharedPreferences(spName,
+ Context.MODE_PRIVATE);
+ Editor editor = sp.edit();
+ editor.remove(key);
+ editSubmit(editor);
+ }
+
+ /**
+ * 清除所有数据
+ *
+ * @param context 上下文
+ */
+ public static void clear(Context context) {
+ clear(context, APP_SHARD);
+ }
+
+ public static void clear(Context context, String spName) {
+ SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
+ Editor editor = sp.edit();
+ editor.clear();
+ editSubmit(editor);
+ }
+
+ /**
+ * 查询某个key是否已经存在
+ *
+ * @param context 上下文
+ * @param key key
+ */
+ public static boolean contains(Context context, String key) {
+ return contains(context, APP_SHARD, key);
+ }
+
+ public static boolean contains(Context context, String spName, String key) {
+ SharedPreferences sp = context.getSharedPreferences(spName, Context.MODE_PRIVATE);
+ return sp.contains(key);
+ }
+
+ /**
+ * 返回所有的键值对
+ *
+ * @param context 上下文
+ */
+ public static Map<String, ?> getAll(Context context) {
+ return getAll(context, APP_SHARD);
+ }
+
+ public static Map<String, ?> getAll(Context context, String spName) {
+ SharedPreferences sp = context.getSharedPreferences(spName,
+ Context.MODE_PRIVATE);
+ return sp.getAll();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/app/src/main/java/com/baidu/duer/dcs/wakeup/WakeUp.java Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2017 Baidu, Inc. 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.baidu.duer.dcs.wakeup;
+
+import com.baidu.duer.dcs.systeminterface.IAudioRecord;
+import com.baidu.duer.dcs.systeminterface.IWakeUp;
+
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * 本地唤醒服务
+ * <p>
+ * Created by guxiuzhong@baidu.com on 2017/6/22.
+ */
+public class WakeUp {
+ private IWakeUp iWakeUp;
+ private List<IWakeUp.IWakeUpListener> wakeUpListeners;
+ private IAudioRecord iAudioRecord;
+
+ public WakeUp(IWakeUp iWakeUp, IAudioRecord iAudioRecord) {
+ this.iWakeUp = iWakeUp;
+ this.iAudioRecord = iAudioRecord;
+ this.wakeUpListeners = Collections.synchronizedList(new LinkedList<IWakeUp.IWakeUpListener>());
+ this.iWakeUp.addWakeUpListener(new IWakeUp.IWakeUpListener() {
+ @Override
+ public void onWakeUpSucceed() {
+ fireOnWakeUpSucceed();
+ }
+ });
+ // 启动音频采集
+ this.iAudioRecord.startRecord();
+ }
+
+ private void fireOnWakeUpSucceed() {
+ for (IWakeUp.IWakeUpListener listener : wakeUpListeners) {
+ listener.onWakeUpSucceed();
+ }
+ }
+
+ /**
+ * 开始唤醒,麦克风处于打开状态,一旦检测到有音频开始唤醒解码
+ */
+ public void startWakeUp() {
+ iWakeUp.startWakeUp();
+ }
+
+ /**
+ * 停止唤醒,关闭麦克风
+ */
+ public void stopWakeUp() {
+ iWakeUp.stopWakeUp();
+ }
+
+ /**
+ * 释放资源-解码so库资源
+ */
+ public void releaseWakeUp() {
+ iAudioRecord.stopRecord();
+ iWakeUp.releaseWakeUp();
+ }
+
+ /**
+ * 添加唤醒成功后的监听
+ */
+ public void addWakeUpListener(IWakeUp.IWakeUpListener listener) {
+ wakeUpListeners.add(listener);
+ }
+
+ public void removeWakeUpListener(IWakeUp.IWakeUpListener listener) {
+ if (wakeUpListeners.contains(listener)) {
+ wakeUpListeners.remove(listener);
+ }
+ }
+}
\ No newline at end of file
Binary file dcs-sdk-java-master/app/src/main/jniLibs/arm64-v8a/libbdEASRAndroid.so has changed
Binary file dcs-sdk-java-master/app/src/main/jniLibs/arm64-v8a/libbdEasrS1MergeNormal.so has changed
Binary file dcs-sdk-java-master/app/src/main/jniLibs/armeabi-v7a/libbdEASRAndroid.so has changed
Binary file dcs-sdk-java-master/app/src/main/jniLibs/armeabi-v7a/libbdEasrS1MergeNormal.so has changed
Binary file dcs-sdk-java-master/app/src/main/jniLibs/armeabi/libbdEASRAndroid.so has changed
Binary file dcs-sdk-java-master/app/src/main/jniLibs/armeabi/libbdEasrS1MergeNormal.so has changed
Binary file dcs-sdk-java-master/app/src/main/jniLibs/x86/libbdEASRAndroid.so has changed
Binary file dcs-sdk-java-master/app/src/main/jniLibs/x86/libbdEasrS1MergeNormal.so has changed
Binary file dcs-sdk-java-master/app/src/main/jniLibs/x86_64/libbdEASRAndroid.so has changed
Binary file dcs-sdk-java-master/app/src/main/jniLibs/x86_64/libbdEasrS1MergeNormal.so has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/src/main/res/drawable/btn_bg.xml Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_window_focused="false"> + <shape> + <solid android:color="@color/color_ff1247c2" /> + <corners android:radius="150dp" /> + + </shape> + </item> + <item android:state_focused="true"> + <shape> + <solid android:color="@color/color_aa1247c2" /> + <corners android:radius="150dp" /> + <stroke android:width="1dp" android:color="@color/color_aa1247c2" /> + </shape> + + </item> + <item android:state_pressed="true"> + <shape> + <solid android:color="@color/color_aa1247c2" /> + <corners android:radius="150dp" /> + <stroke android:width="1dp" android:color="@color/color_aa1247c2" /> + </shape> + + </item> +</selector> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/src/main/res/layout/dcs_sample_activity_main.xml Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,104 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@color/color_f5f5f5" + android:orientation="vertical"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_horizontal" + android:text="@string/wakeup_word" + android:textColor="@android:color/black" + android:textSize="18dp" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:orientation="vertical"> + + <ScrollView + android:id="@+id/id_sv_request" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <LinearLayout + android:id="@+id/topLinearLayout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" /> + </ScrollView> + </LinearLayout> + + + <LinearLayout + android:id="@+id/songLinearLayout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:orientation="horizontal"> + + <Button + android:id="@+id/previousSongBtn" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="@string/previous_audio" /> + + <Button + android:id="@+id/pauseOrPlayBtn" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="@string/audio_default" /> + + <Button + android:id="@+id/nextSongBtn" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" + android:text="@string/next_audio" /> + + </LinearLayout> + + <TextView + android:id="@+id/id_tv_time_0" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="@android:color/black" + android:textSize="16dp" /> + + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="10dp" + android:orientation="horizontal"> + + <Button + android:id="@+id/voiceBtn" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_margin="10dp" + android:layout_weight="1" + android:background="@drawable/btn_bg" + android:text="@string/stop_record" + android:textColor="@android:color/white" + android:textSize="16dp" /> + + <Button + android:id="@+id/openLogBtn" + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_margin="10dp" + android:layout_weight="1" + android:background="@drawable/btn_bg" + android:text="@string/open_log" + android:textColor="@android:color/white" + android:textSize="16dp" /> + + </LinearLayout> + +</LinearLayout>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/src/main/res/layout/dcs_sample_activity_oauth.xml Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <TextView + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:text="@string/client_id" + android:textSize="16sp" /> + + <EditText + android:id="@+id/edit_client_id" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:enabled="false" /> + + <Button + android:id="@+id/btn_login" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="10dp" + android:background="@drawable/btn_bg" + android:text="@string/login" + android:textColor="@android:color/white" /> + +</LinearLayout>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/src/main/res/layout/dcs_sample_activity_oauth_login.xml Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <RelativeLayout + android:id="@+id/containerLayout" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + + <WebView + android:id="@+id/oauthWeb" + android:layout_width="match_parent" + android:layout_height="match_parent" /> +</LinearLayout> \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/src/main/res/layout/dcs_sample_activity_screen_html.xml Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" android:layout_height="match_parent"> + + <RelativeLayout + android:id="@+id/relativeLayout" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + </RelativeLayout> +</RelativeLayout> \ No newline at end of file
Binary file dcs-sdk-java-master/app/src/main/res/mipmap-hdpi/ic_launcher.png has changed
Binary file dcs-sdk-java-master/app/src/main/res/mipmap-mdpi/ic_launcher.png has changed
Binary file dcs-sdk-java-master/app/src/main/res/mipmap-xhdpi/ic_launcher.png has changed
Binary file dcs-sdk-java-master/app/src/main/res/mipmap-xxhdpi/ic_launcher.png has changed
Binary file dcs-sdk-java-master/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/src/main/res/values/colors.xml Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="colorPrimary">#3F51B5</color> + <color name="colorPrimaryDark">#303F9F</color> + <color name="colorAccent">#FF4081</color> + + <color name="color_ff1247c2">#ff1247c2</color> + <color name="color_aa1247c2">#aa1247c2</color> + <color name="color_transparent">#00000000</color> + <color name="color_f5f5f5">#f5f5f5</color> +</resources>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/src/main/res/values/strings.xml Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,25 @@ +<resources> + <string name="app_name">DcsSampleApp</string> + <string name="err_net_msg">当前网络连接失败,请稍后重试</string> + <string name="voice_err_msg">识别失败,请稍后再试</string> + <string name="audio_paused">暂停中…</string> + <string name="audio_playing">播放中…</string> + <string name="audio_default">等待音乐</string> + <string name="stop_record">点击说话</string> + <string name="start_record">录音中…</string> + <string name="time_record">耗时:click->StopListen:%1$dms</string> + <string name="request_error">出错了,请稍后再试</string> + <string name="no_log">暂时没有日志</string> + <string name="no_directive">对不起,暂时没有收到指令</string> + <string name="no_audio">暂时没有歌曲了,请稍后再试</string> + <string name="open_file_title">选择浏览工具</string> + <string name="previous_audio">上一首</string> + <string name="next_audio">下一首</string> + <string name="open_log">打开日志</string> + <string name="login">登陆</string> + <string name="client_id">您应用的client_id</string> + <string name="client_id_empty">请输入您申请的client_id</string> + <string name="login_succeed">登陆成功</string> + <string name="wakeup_succeed">唤醒成功,您问点什么呢?</string> + <string name="wakeup_word">您可以说【小度小度】进行唤醒</string> +</resources>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/app/src/main/res/values/styles.xml Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,20 @@ +<resources> + + <!-- Base application theme. --> + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> + <!-- Customize your theme here. --> + <item name="colorPrimary">@color/colorPrimary</item> + <item name="colorPrimaryDark">@color/colorPrimaryDark</item> + <item name="colorAccent">@color/colorAccent</item> + </style> + + <style name="AppTheme.NoActionBar"> + <item name="windowActionBar">false</item> + <item name="windowNoTitle">true</item> + </style> + + <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" /> + + <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" /> + +</resources>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/build.gradle Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,23 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+
+buildscript {
+ repositories {
+ jcenter()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:2.2.3'
+
+ // NOTE: Do not place your application dependencies here; they belong
+ // in the individual module build.gradle files
+ }
+}
+
+allprojects {
+ repositories {
+ jcenter()
+ }
+}
+
+task clean(type: Delete) {
+ delete rootProject.buildDir
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/gradle.properties Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,17 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx1536m + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true
Binary file dcs-sdk-java-master/gradle/wrapper/gradle-wrapper.jar has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/gradle/wrapper/gradle-wrapper.properties Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,6 @@ +#Mon Dec 28 10:00:20 PST 2015 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dcs-sdk-java-master/gradlew Tue Jul 18 16:34:48 2017 +0800
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+ echo "$*"
+}
+
+die ( ) {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+ JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/gradlew.bat Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega
Binary file dcs-sdk-java-master/images/access-architecture.png has changed
Binary file dcs-sdk-java-master/images/client-id-secret.png has changed
Binary file dcs-sdk-java-master/images/login1.png has changed
Binary file dcs-sdk-java-master/images/login2.png has changed
Binary file dcs-sdk-java-master/images/modify-client-id.png has changed
Binary file dcs-sdk-java-master/images/project.png has changed
Binary file dcs-sdk-java-master/images/sdk-architecture.png has changed
Binary file dcs-sdk-java-master/images/wakeup.png has changed
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dcs-sdk-java-master/settings.gradle Tue Jul 18 16:34:48 2017 +0800 @@ -0,0 +1,1 @@ +include ':app'
