Sorry, the page you are looking for is currently unavailable.
16 | Please try again later.
If you are the system administrator of this resource then you should check 18 | the error log for details.
19 |Faithfully yours, nginx.
20 | 21 | 22 | -------------------------------------------------------------------------------- /nginxserver/src/main/assets/nginx/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |If you see this page, the nginx web server is successfully installed and 16 | working. Further configuration is required.
17 | 18 |For online documentation and support please refer to
19 | nginx.org.
20 | Commercial support is available at
21 | nginx.com.
Thank you for using nginx.
24 | 25 | 26 | -------------------------------------------------------------------------------- /nginxserver/src/main/assets/nginx/logs/error.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javaertj/simpledlna/b23c824fc83b1b1d1fa337b52301aa41e9a37526/nginxserver/src/main/assets/nginx/logs/error.log -------------------------------------------------------------------------------- /nginxserver/src/main/assets/nginx/logs/nginx.pid: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javaertj/simpledlna/b23c824fc83b1b1d1fa337b52301aa41e9a37526/nginxserver/src/main/assets/nginx/logs/nginx.pid -------------------------------------------------------------------------------- /nginxserver/src/main/assets/nginx/sbin/nginx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javaertj/simpledlna/b23c824fc83b1b1d1fa337b52301aa41e9a37526/nginxserver/src/main/assets/nginx/sbin/nginx -------------------------------------------------------------------------------- /nginxserver/src/main/assets/nginx/temp/hls/test.hls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javaertj/simpledlna/b23c824fc83b1b1d1fa337b52301aa41e9a37526/nginxserver/src/main/assets/nginx/temp/hls/test.hls -------------------------------------------------------------------------------- /nginxserver/src/main/java/com/ykbjson/lib/nginxserver/nginx/NginxHelper.java: -------------------------------------------------------------------------------- 1 | package com.ykbjson.lib.nginxserver.nginx; 2 | 3 | import android.content.Context; 4 | import android.content.res.AssetManager; 5 | import android.util.Log; 6 | 7 | import androidx.annotation.NonNull; 8 | 9 | import com.jrummyapps.android.shell.CommandResult; 10 | import com.jrummyapps.android.shell.Shell; 11 | 12 | import java.io.File; 13 | import java.io.FileOutputStream; 14 | import java.io.IOException; 15 | import java.io.InputStream; 16 | import java.io.OutputStream; 17 | 18 | /** 19 | * Description:Ngiinx服务器帮助类 20 | *19 | * TODO: should do a best-fit match, e.g. 20 | * https://github.com/commonsguy/cwac-camera/blob/master/camera/src/com/commonsware/cwac/camera/CameraUtils.java 21 | */ 22 | public static void choosePreviewSize(Camera.Parameters parms, int width, int height) { 23 | // We should make sure that the requested MPEG size is less than the preferred 24 | // size, and has the same aspect ratio. 25 | Camera.Size ppsfv = parms.getPreferredPreviewSizeForVideo(); 26 | if (ppsfv != null) { 27 | Log.d(TAG, "Camera preferred preview size for video is " + 28 | ppsfv.width + "x" + ppsfv.height); 29 | } 30 | 31 | //for (Camera.Size size : parms.getSupportedPreviewSizes()) { 32 | // Log.d(TAG, "supported: " + size.width + "x" + size.height); 33 | //} 34 | 35 | for (Camera.Size size : parms.getSupportedPreviewSizes()) { 36 | if (size.width == width && size.height == height) { 37 | parms.setPreviewSize(width, height); 38 | return; 39 | } 40 | } 41 | 42 | Log.w(TAG, "Unable to set preview size to " + width + "x" + height); 43 | if (ppsfv != null) { 44 | parms.setPreviewSize(ppsfv.width, ppsfv.height); 45 | } 46 | // else use whatever the default size is 47 | } 48 | 49 | /** 50 | * Attempts to find a fixed preview frame rate that matches the desired frame rate. 51 | *
52 | * It doesn't seem like there's a great deal of flexibility here. 53 | *
54 | * TODO: follow the recipe from http://stackoverflow.com/questions/22639336/#22645327
55 | *
56 | * @return The expected frame rate, in thousands of frames per second.
57 | */
58 | public static int chooseFixedPreviewFps(Camera.Parameters parms, int desiredThousandFps) {
59 | List
14 | * see https://stackoverflow.com/questions/4561345/how-to-configure-java-util-logging-on-android/9047282#9047282
15 | *
16 | *
15 | * Creator:yankebin
16 | *
47 | * By default, files are created by
47 | * This class stores its files in the standard location (that is, wherever
48 | *
42 | * Temp files are responsible for managing the actual temporary storage and
43 | * cleaning themselves up when no longer needed.
44 | *
40 | * Temp file managers are created 1-to-1 with incoming requests, to create and
41 | * cleanup temporary files created as a result of handling the request.
42 | *
46 | * By default, the server spawns a new Thread for every incoming request. These
47 | * are set to daemon status, and named according to the request number.
48 | * The name is useful when profiling the application.
49 | *
16 | * Creator:yankebin
17 | *
18 | * CreatedAt:2019-07-10
19 | */
20 | public class DLNABrowserService extends AndroidUpnpServiceImpl {
21 | @Override
22 | protected UpnpServiceConfiguration createConfiguration() {
23 | return new AndroidUpnpServiceConfiguration() {
24 | @Override
25 | public ServiceDescriptorBinder createServiceDescriptorBinderUDA10() {
26 | return new DLNAUDA10ServiceDescriptorBinderSAXImpl();
27 | }
28 |
29 | // @Override
30 | // public ServiceType[] getExclusiveServiceTypes() {
31 | // return new ServiceType[] {
32 | // new UDAServiceType("AVTransport"),
33 | // new UDAServiceType("ContentDirectory"),
34 | // new UDAServiceType("ConnectionManager"),
35 | // new UDAServiceType("RenderingControl"),
36 | // new UDAServiceType("X_MS_MediaReceiverRegistrar")
37 | // };
38 | // }
39 | };
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/screening/src/main/java/com/ykbjson/lib/screening/RequestMediaProjectionActivity.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screening;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.media.projection.MediaProjection;
6 | import android.media.projection.MediaProjectionManager;
7 | import android.os.Bundle;
8 | import android.view.Gravity;
9 | import android.view.Window;
10 | import android.view.WindowManager;
11 | import android.widget.Toast;
12 |
13 | import androidx.annotation.Nullable;
14 | import androidx.appcompat.app.AppCompatActivity;
15 |
16 | import com.ykbjson.lib.screening.listener.OnRequestMediaProjectionResultCallback;
17 |
18 | /**
19 | * Description:获取录屏的MediaProjection的activity,显示一个像素
20 | *
21 | * Creator:yankebin
22 | *
23 | * CreatedAt:2019-08-06
24 | */
25 | public class RequestMediaProjectionActivity extends AppCompatActivity {
26 | private static final int CODE_REQUEST_MEDIA_PROJECTION = 1012;
27 | static OnRequestMediaProjectionResultCallback resultCallback;
28 | private MediaProjectionManager mMediaProjectionManager;
29 |
30 | @Override
31 | protected void onCreate(@Nullable Bundle savedInstanceState) {
32 | super.onCreate(savedInstanceState);
33 | setContentView(R.layout.activity_request_media_projection);
34 | //window大小设置为1个像素,用户无感知不可见
35 | Window window = getWindow();
36 | window.setGravity(Gravity.LEFT | Gravity.TOP);
37 | WindowManager.LayoutParams params = window.getAttributes();
38 | params.x = 0;
39 | params.y = 0;
40 | params.width = 1;
41 | params.height = 1;
42 | window.setAttributes(params);
43 |
44 | mMediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
45 | }
46 |
47 | @Override
48 | protected void onStart() {
49 | super.onStart();
50 | requestMediaProjection();
51 | }
52 |
53 | @Override
54 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
55 | super.onActivityResult(requestCode, resultCode, data);
56 | if (requestCode == CODE_REQUEST_MEDIA_PROJECTION) {
57 |
58 | MediaProjection mediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data);
59 | if (null == mediaProjection) {
60 | Toast.makeText(this, "你拒绝了录屏操作!", Toast.LENGTH_SHORT).show();
61 | } else if (null != resultCallback) {
62 | resultCallback.onMediaProjectionResult(mediaProjection);
63 | }
64 | finish();
65 | }
66 | }
67 |
68 | @Override
69 | protected void onDestroy() {
70 | resultCallback = null;
71 | super.onDestroy();
72 | }
73 |
74 | private void requestMediaProjection() {
75 | Intent captureIntent = mMediaProjectionManager.createScreenCaptureIntent();
76 | startActivityForResult(captureIntent, CODE_REQUEST_MEDIA_PROJECTION);
77 | }
78 |
79 | static void start(Context context) {
80 | context.startActivity(new Intent(context, RequestMediaProjectionActivity.class)
81 | .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/screening/src/main/java/com/ykbjson/lib/screening/bean/DeviceInfo.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screening.bean;
2 |
3 | import com.ykbjson.lib.screening.DLNAPlayer;
4 |
5 | import org.fourthline.cling.model.meta.Device;
6 |
7 | import java.io.Serializable;
8 |
9 | /**
10 | * Description:设备信息
11 | *
12 | * Creator:yankebin
13 | *
14 | * CreatedAt:2019-07-09
15 | */
16 | public class DeviceInfo implements Serializable {
17 | private Device device;
18 | private String name;
19 | private String mediaID;
20 | private String oldMediaID;
21 | private int state = DLNAPlayer.UNKNOWN;
22 | private boolean connected;
23 |
24 | public DeviceInfo(Device device, String name) {
25 | this.device = device;
26 | this.name = name;
27 | }
28 |
29 | public DeviceInfo() {
30 | }
31 |
32 | public Device getDevice() {
33 | return this.device;
34 | }
35 |
36 | public void setDevice(Device device) {
37 | this.device = device;
38 | }
39 |
40 | public String getName() {
41 | return this.name;
42 | }
43 |
44 | public void setName(String name) {
45 | this.name = name;
46 | }
47 |
48 | public void setMediaID(String mediaId) {
49 | this.mediaID = mediaId;
50 | }
51 |
52 | public String getMediaID() {
53 | return this.mediaID;
54 | }
55 |
56 | public void setOldMediaID(String oldMediaID) {
57 | this.oldMediaID = oldMediaID;
58 | }
59 |
60 | public String getOldMediaID() {
61 | return this.oldMediaID;
62 | }
63 |
64 | public int getState() {
65 | return state;
66 | }
67 |
68 | public void setState(int state) {
69 | this.state = state;
70 | }
71 |
72 | public boolean isConnected() {
73 | return connected;
74 | }
75 |
76 | public void setConnected(boolean connected) {
77 | this.connected = connected;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/screening/src/main/java/com/ykbjson/lib/screening/bean/MediaInfo.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screening.bean;
2 |
3 | /**
4 | * Description:多媒体信息
5 | *
6 | * Creator:yankebin
7 | *
8 | * CreatedAt:2019-07-09
9 | */
10 | public class MediaInfo {
11 | public static final int TYPE_UNKNOWN = 0;
12 | public static final int TYPE_IMAGE = 1;
13 | public static final int TYPE_VIDEO = 2;
14 | public static final int TYPE_AUDIO = 3;
15 | public static final int TYPE_MIRROR = 4;
16 |
17 | private String mediaName;
18 | private String mediaId;
19 | private int mediaType = TYPE_UNKNOWN;
20 | private String uri;
21 | private String filePath;
22 | private long duration;
23 | private String bulbulName;
24 | private String theAlbumName;
25 | private int index;
26 |
27 | public String getMediaName() {
28 | return this.mediaName;
29 | }
30 |
31 | public void setMediaName(String mediaName) {
32 | this.mediaName = mediaName;
33 | }
34 |
35 | public String getMediaId() {
36 | return this.mediaId;
37 | }
38 |
39 | public void setMediaId(String mediaId) {
40 | this.mediaId = mediaId;
41 | }
42 |
43 | public int getMediaType() {
44 | return this.mediaType;
45 | }
46 |
47 | public void setMediaType(int mediaType) {
48 | this.mediaType = mediaType;
49 | }
50 |
51 | public String getUri() {
52 | return this.uri;
53 | }
54 |
55 | public void setUri(String uri) {
56 | this.uri = uri;
57 | }
58 |
59 | public String getFilePath() {
60 | return this.filePath;
61 | }
62 |
63 | public void setFilePath(String filePath) {
64 | this.filePath = filePath;
65 | }
66 |
67 | public long getDuration() {
68 | return this.duration;
69 | }
70 |
71 | public void setDuration(long duration) {
72 | this.duration = duration;
73 | }
74 |
75 | public String getBulbulName() {
76 | return this.bulbulName;
77 | }
78 |
79 | public void setBulbulName(String bulbulName) {
80 | this.bulbulName = bulbulName;
81 | }
82 |
83 | public String getTheAlbumName() {
84 | return this.theAlbumName;
85 | }
86 |
87 | public void setTheAlbumName(String theAlbumName) {
88 | this.theAlbumName = theAlbumName;
89 | }
90 |
91 | public int getIndex() {
92 | return this.index;
93 | }
94 |
95 | public void setIndex(int index) {
96 | this.index = index;
97 | }
98 | }
--------------------------------------------------------------------------------
/screening/src/main/java/com/ykbjson/lib/screening/listener/DLNAControlCallback.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screening.listener;
2 |
3 |
4 | import androidx.annotation.IntRange;
5 | import androidx.annotation.Nullable;
6 |
7 | import org.fourthline.cling.model.action.ActionInvocation;
8 |
9 | /**
10 | * Description:DLNA执行命令回调接口
11 | *
12 | * Creator:yankebin
13 | *
14 | * CreatedAt:2019-07-10
15 | */
16 | public interface DLNAControlCallback {
17 | int ERROR_CODE_NO_ERROR = 0;
18 |
19 | int ERROR_CODE_RE_PLAY = 1;
20 |
21 | int ERROR_CODE_RE_PAUSE = 2;
22 |
23 | int ERROR_CODE_RE_STOP = 3;
24 |
25 | int ERROR_CODE_DLNA_ERROR = 4;
26 |
27 | int ERROR_CODE_SERVICE_ERROR = 5;
28 |
29 | int ERROR_CODE_NOT_READY = 6;
30 |
31 | int ERROR_CODE_BIND_SCREEN_RECORDER_SERVICE_ERROR = 7;
32 |
33 |
34 | void onSuccess(@Nullable ActionInvocation invocation);
35 |
36 | void onReceived(@Nullable ActionInvocation invocation, @Nullable Object... extra);
37 |
38 | void onFailure(@Nullable ActionInvocation invocation,
39 | @IntRange(from = ERROR_CODE_NO_ERROR, to = ERROR_CODE_BIND_SCREEN_RECORDER_SERVICE_ERROR) int errorCode,
40 | @Nullable String errorMsg);
41 | }
42 |
--------------------------------------------------------------------------------
/screening/src/main/java/com/ykbjson/lib/screening/listener/DLNADeviceConnectListener.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screening.listener;
2 |
3 | import com.ykbjson.lib.screening.bean.DeviceInfo;
4 |
5 | /**
6 | * Description:连接设备的回调接口
7 | *
8 | * Creator:yankebin
9 | *
10 | * CreatedAt:2019-07-09
11 | */
12 | public interface DLNADeviceConnectListener {
13 |
14 | int TYPE_DLNA = 1;
15 | int TYPE_IM = 2;
16 | int TYPE_NEW_LELINK = 3;
17 | int CONNECT_INFO_CONNECT_SUCCESS = 100000;
18 | int CONNECT_INFO_CONNECT_FAILURE = 100001;
19 | int CONNECT_INFO_DISCONNECT = 212000;
20 | int CONNECT_INFO_DISCONNECT_SUCCESS = 212001;
21 | int CONNECT_ERROR_FAILED = 212010;
22 | int CONNECT_ERROR_IO = 212011;
23 | int CONNECT_ERROR_IM_WAITTING = 212012;
24 | int CONNECT_ERROR_IM_REJECT = 212013;
25 | int CONNECT_ERROR_IM_TIMEOUT = 212014;
26 | int CONNECT_ERROR_IM_BLACKLIST = 212015;
27 |
28 | void onConnect(DeviceInfo deviceInfo, int errorCode);
29 |
30 | void onDisconnect(DeviceInfo deviceInfo,int type,int errorCode);
31 | }
32 |
--------------------------------------------------------------------------------
/screening/src/main/java/com/ykbjson/lib/screening/listener/DLNAStateCallback.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screening.listener;
2 |
3 | /**
4 | * Description:DLNAManager初始化回调接口
5 | *
6 | * Creator:yankebin
7 | *
8 | * CreatedAt:2019-07-09
9 | */
10 | public interface DLNAStateCallback {
11 |
12 | void onConnected();
13 |
14 | void onDisconnected();
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/screening/src/main/java/com/ykbjson/lib/screening/listener/OnRequestMediaProjectionResultCallback.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screening.listener;
2 |
3 | import android.media.projection.MediaProjection;
4 |
5 | import androidx.annotation.UiThread;
6 |
7 | /**
8 | * Description:获取录屏的MediaProjection的回调
9 | *
10 | * Creator:yankebin
11 | *
12 | * CreatedAt:2019-08-06
13 | */
14 | public interface OnRequestMediaProjectionResultCallback {
15 | @UiThread
16 | void onMediaProjectionResult(MediaProjection mediaProjection);
17 | }
18 |
--------------------------------------------------------------------------------
/screening/src/main/java/com/ykbjson/lib/screening/log/AndroidLoggingHandler.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screening.log;
2 |
3 | import android.util.Log;
4 |
5 | import java.util.logging.Handler;
6 | import java.util.logging.Level;
7 | import java.util.logging.LogManager;
8 | import java.util.logging.LogRecord;
9 | import java.util.logging.Logger;
10 |
11 | /**
12 | * Description:How to configure java.util.logging on Android?
13 | *
17 | * Creator:yankebin
18 | *
19 | * CreatedAt:2019-07-19
20 | */
21 |
22 | public final class AndroidLoggingHandler extends Handler {
23 |
24 | public static void injectJavaLogger() {
25 | Logger rootLogger = LogManager.getLogManager().getLogger("");
26 | Handler[] handlers = rootLogger.getHandlers();
27 | for (Handler handler : handlers) {
28 | rootLogger.removeHandler(handler);
29 | }
30 | rootLogger.addHandler(new AndroidLoggingHandler());
31 | Logger.getLogger("my.category").setLevel(Level.FINEST);
32 | }
33 |
34 | @Override
35 | public void close() {
36 | }
37 |
38 | @Override
39 | public void flush() {
40 | }
41 |
42 | @Override
43 | public void publish(LogRecord record) {
44 | if (!super.isLoggable(record))
45 | return;
46 |
47 | String name = record.getLoggerName();
48 | int maxLength = 30;
49 | String tag = name.length() > maxLength ? name.substring(name.length() - maxLength) : name;
50 |
51 | try {
52 | int level = getAndroidLevel(record.getLevel());
53 | Log.println(level, tag, record.getMessage());
54 | if (record.getThrown() != null) {
55 | Log.println(level, tag, Log.getStackTraceString(record.getThrown()));
56 | }
57 | } catch (RuntimeException e) {
58 | Log.e("AndroidLoggingHandler", "Error logging message.", e);
59 | }
60 | }
61 |
62 | static int getAndroidLevel(Level level) {
63 | int value = level.intValue();
64 |
65 | if (value >= Level.SEVERE.intValue()) {
66 | return Log.ERROR;
67 | } else if (value >= Level.WARNING.intValue()) {
68 | return Log.WARN;
69 | } else if (value >= Level.INFO.intValue()) {
70 | return Log.INFO;
71 | } else {
72 | return Log.DEBUG;
73 | }
74 | }
75 | }
--------------------------------------------------------------------------------
/screening/src/main/java/com/ykbjson/lib/screening/xml/DLNASAXParser.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screening.xml;
2 |
3 |
4 | import org.seamless.xml.SAXParser;
5 | import org.xml.sax.XMLReader;
6 |
7 | import javax.xml.parsers.SAXParserFactory;
8 |
9 | /**
10 | * Description:DLNASAXParser
11 | *
12 | * Creator:yankebin
13 | *
14 | * CreatedAt:2019-07-10
15 | */
16 | public class DLNASAXParser extends SAXParser {
17 |
18 | protected XMLReader create() {
19 | try {
20 | SAXParserFactory factory = SAXParserFactory.newInstance();
21 |
22 | // Configure factory to prevent XXE attacks
23 | factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
24 | factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
25 | //解决创建解析器报错的问题
26 | // factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
27 | // //fix bug .see https://stackoverflow.com/questions/10837706/solve-security-issue-parsing-xml-using-sax-parser
28 | // factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
29 |
30 | // factory.setXIncludeAware(false);
31 | //
32 | // factory.setNamespaceAware(true);
33 |
34 | if (getSchemaSources() != null) {
35 | factory.setSchema(createSchema(getSchemaSources()));
36 | }
37 |
38 | XMLReader xmlReader = factory.newSAXParser().getXMLReader();
39 | xmlReader.setErrorHandler(getErrorHandler());
40 | return xmlReader;
41 | } catch (Exception ex) {
42 | throw new RuntimeException(ex);
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/screening/src/main/java/com/ykbjson/lib/screening/xml/DLNAUDA10ServiceDescriptorBinderSAXImpl.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screening.xml;
2 |
3 |
4 | import com.ykbjson.lib.screening.DLNAManager;
5 |
6 | import org.fourthline.cling.binding.staging.MutableService;
7 | import org.fourthline.cling.binding.xml.DescriptorBindingException;
8 | import org.fourthline.cling.binding.xml.UDA10ServiceDescriptorBinderSAXImpl;
9 | import org.fourthline.cling.model.ValidationException;
10 | import org.fourthline.cling.model.meta.Service;
11 | import org.seamless.xml.SAXParser;
12 | import org.xml.sax.InputSource;
13 |
14 | import java.io.StringReader;
15 |
16 | /**
17 | * Description:DLNAUDA10ServiceDescriptorBinderSAXImpl
18 | *
19 | * Creator:yankebin
20 | *
21 | * CreatedAt:2019-07-10
22 | */
23 | public class DLNAUDA10ServiceDescriptorBinderSAXImpl extends UDA10ServiceDescriptorBinderSAXImpl {
24 |
25 | private static final String TAG = DLNAUDA10ServiceDescriptorBinderSAXImpl.class.getSimpleName();
26 |
27 | @Override
28 | public S describe(S undescribedService, String descriptorXml) throws DescriptorBindingException, ValidationException {
29 | if (descriptorXml == null || descriptorXml.length() == 0) {
30 | throw new DescriptorBindingException("Null or empty descriptor");
31 | }
32 |
33 | try {
34 |
35 | DLNAManager.logD(TAG, "Reading service from XML descriptor, content : \n" + descriptorXml);
36 |
37 | SAXParser parser = new DLNASAXParser();
38 |
39 | MutableService descriptor = new MutableService();
40 |
41 | hydrateBasic(descriptor, undescribedService);
42 |
43 | new RootHandler(descriptor, parser);
44 |
45 | parser.parse(
46 | new InputSource(
47 | // TODO: UPNP VIOLATION: Virgin Media Superhub sends trailing spaces/newlines after last XML element, need to trim()
48 | new StringReader(descriptorXml.trim())
49 | )
50 | );
51 |
52 | // Build the immutable descriptor graph
53 | return (S) descriptor.build(undescribedService.getDevice());
54 |
55 | } catch (ValidationException ex) {
56 | throw ex;
57 | } catch (Exception ex) {
58 | throw new DescriptorBindingException("Could not parse service descriptor: " + ex.toString(), ex);
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/screening/src/main/res/layout/activity_request_media_projection.xml:
--------------------------------------------------------------------------------
1 |
2 |
15 | * Creator:yankebin
16 | *
17 | * CreatedAt:2019-07-29
18 | */
19 | public class AudioEncodeConfig {
20 | final String codecName;
21 | final String mimeType;
22 | final int bitRate;
23 | final int sampleRate;
24 | final int channelCount;
25 | final int profile;
26 |
27 |
28 | private AudioEncodeConfig(Builder builder) {
29 | this(builder.codecName, builder.mimeType, builder.bitrate, builder.simpleRate,
30 | builder.channelCount, builder.profile);
31 | }
32 |
33 | public AudioEncodeConfig(String codecName, String mimeType,
34 | int bitRate, int sampleRate, int channelCount, int profile) {
35 | this.codecName = codecName;
36 | this.mimeType = Objects.requireNonNull(mimeType);
37 | this.bitRate = bitRate;
38 | this.sampleRate = sampleRate;
39 | this.channelCount = channelCount;
40 | this.profile = profile;
41 | }
42 |
43 |
44 | MediaFormat toFormat() {
45 | MediaFormat format = MediaFormat.createAudioFormat(mimeType, sampleRate, channelCount);
46 | format.setInteger(MediaFormat.KEY_AAC_PROFILE, profile);
47 | format.setInteger(MediaFormat.KEY_BIT_RATE, bitRate);
48 | //format.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 4096 * 4);
49 | return format;
50 | }
51 |
52 | @Override
53 | public String toString() {
54 | return "AudioEncodeConfig{" +
55 | "codecName='" + codecName + '\'' +
56 | ", mimeType='" + mimeType + '\'' +
57 | ", bitRate=" + bitRate +
58 | ", sampleRate=" + sampleRate +
59 | ", channelCount=" + channelCount +
60 | ", profile=" + profile +
61 | '}';
62 | }
63 |
64 | public static final class Builder {
65 | private String codecName;
66 | private String mimeType = AUDIO_AAC;
67 | private int bitrate = 80 * 1000;
68 | private int simpleRate = 44100;
69 | private int channelCount = 2;
70 | private int profile = MediaCodecInfo.CodecProfileLevel.AACObjectMain;
71 |
72 | public Builder() {
73 | final MediaCodecInfo[] infos = Utils.getmAacCodecInfos();
74 | if (null != infos && infos.length > 0) {
75 | codecName = infos[0].getName();
76 | }
77 | }
78 |
79 | public static Builder create() {
80 | return new Builder();
81 | }
82 |
83 | public Builder codecName(@NonNull String codecName) {
84 | this.codecName = codecName;
85 | return this;
86 | }
87 |
88 | public Builder mimeType(@NonNull String mimeType) {
89 | this.mimeType = mimeType;
90 | return this;
91 | }
92 |
93 | public Builder bitrate(int bitrate) {
94 | this.bitrate = bitrate;
95 | return this;
96 | }
97 |
98 | public Builder simpleRate(int simpleRate) {
99 | this.simpleRate = simpleRate;
100 | return this;
101 | }
102 |
103 | public Builder channelCount(int channelCount) {
104 | this.channelCount = channelCount;
105 | return this;
106 | }
107 |
108 | public Builder profile(int profile) {
109 | this.profile = profile;
110 | return this;
111 | }
112 |
113 | public AudioEncodeConfig build() {
114 | return new AudioEncodeConfig(this);
115 | }
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/screenrecorder/src/main/java/com/ykbjson/lib/screenrecorder/AudioEncoder.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screenrecorder;
2 |
3 | import android.media.MediaFormat;
4 |
5 |
6 | /**
7 | * Description:音频编码器
8 | *
9 | * Creator:yankebin
10 | *
11 | * CreatedAt:2019-07-29
12 | */
13 | class AudioEncoder extends BaseEncoder {
14 | private final AudioEncodeConfig mConfig;
15 |
16 | AudioEncoder(AudioEncodeConfig config) {
17 | super(config.codecName);
18 | this.mConfig = config;
19 | }
20 |
21 | @Override
22 | protected MediaFormat createMediaFormat() {
23 | return mConfig.toFormat();
24 | }
25 |
26 | AudioEncodeConfig getConfig() {
27 | return mConfig;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/screenrecorder/src/main/java/com/ykbjson/lib/screenrecorder/Encoder.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screenrecorder;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * Description:编码器接口
7 | *
8 | * Creator:yankebin
9 | *
10 | * CreatedAt:2019-07-29
11 | */
12 | interface Encoder {
13 | void prepare() throws IOException;
14 |
15 | void stop();
16 |
17 | void release();
18 |
19 | void setCallback(Callback callback);
20 |
21 | interface Callback {
22 | void onError(Encoder encoder, Exception exception);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/screenrecorder/src/main/java/com/ykbjson/lib/screenrecorder/IRecorderCallback.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screenrecorder;
2 |
3 | import android.media.MediaCodec;
4 |
5 | /**
6 | * Description:录屏状态回调接口
7 | *
8 | * Creator:yankebin
9 | *
10 | * CreatedAt:2019-07-31
11 | */
12 | public interface IRecorderCallback {
13 |
14 | void onPrepareRecord();
15 |
16 | void onStartRecord();
17 |
18 | void onRecording(long presentationTimeUs);
19 |
20 | void onStopRecord(Throwable error);
21 |
22 | void onDestroyRecord();
23 |
24 | void onMuxVideo(byte[] buffer, int offset, int length, MediaCodec.BufferInfo bufferInfo);
25 |
26 | void onMuxAudio(byte[] buffer, int offset, int length, MediaCodec.BufferInfo bufferInfo);
27 | }
28 |
--------------------------------------------------------------------------------
/screenrecorder/src/main/java/com/ykbjson/lib/screenrecorder/IScreenRecorderService.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screenrecorder;
2 |
3 | import android.media.projection.MediaProjection;
4 |
5 | /**
6 | * Description:录屏服务
7 | *
8 | * The default implementation requires permissions in AndroidManifest.xml
:
9 | * {@code
11 | *
14 | *
17 | * CreatedAt:2019-07-31
18 | */
19 | public interface IScreenRecorderService {
20 |
21 | void registerRecorderCallback(IRecorderCallback callback);
22 |
23 | void prepareAndStartRecorder(MediaProjection mediaProjection, VideoEncodeConfig videoConfig,
24 | AudioEncodeConfig audioConfig);
25 |
26 | void startRecorder(VideoEncodeConfig videoConfig, AudioEncodeConfig audioConfig);
27 |
28 | void startRecorder();
29 |
30 | void stopRecorder();
31 |
32 | void destroyRecorder();
33 |
34 | String getSavingFilePath();
35 |
36 | VideoEncodeConfig getVideoEncodeConfig();
37 |
38 | AudioEncodeConfig getAudioEncodeConfig();
39 |
40 | boolean hasPrepared();
41 | }
42 |
--------------------------------------------------------------------------------
/screenrecorder/src/main/java/com/ykbjson/lib/screenrecorder/IScreenRecorderServiceProxy.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screenrecorder;
2 |
3 | /**
4 | * Description:录屏服务中转接口
5 | *
6 | * Creator:yankebin
7 | *
8 | * CreatedAt:2019-07-31
9 | */
10 | interface IScreenRecorderServiceProxy extends IScreenRecorderService {
11 | IScreenRecorderService get();
12 | }
13 |
--------------------------------------------------------------------------------
/screenrecorder/src/main/java/com/ykbjson/lib/screenrecorder/Notifications.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screenrecorder;
2 |
3 | import android.annotation.TargetApi;
4 | import android.app.Notification;
5 | import android.app.NotificationChannel;
6 | import android.app.NotificationManager;
7 | import android.app.PendingIntent;
8 | import android.content.Context;
9 | import android.content.ContextWrapper;
10 | import android.content.Intent;
11 | import android.os.Build;
12 | import android.os.SystemClock;
13 | import android.text.format.DateUtils;
14 |
15 | import static android.os.Build.VERSION_CODES.O;
16 |
17 | /**
18 | * Description:通知帮助类,录屏属于隐私操作,需要用户时刻注意到
19 | *
20 | * Creator:yankebin
21 | *
22 | * CreatedAt:2019-07-30
23 | */
24 | public class Notifications extends ContextWrapper {
25 |
26 | public static final String ACTION_STOP = BuildConfig.APPLICATION_ID + ".action.STOP";
27 |
28 | protected long mLastFiredTime = 0;
29 | protected NotificationManager mManager;
30 | protected Notification.Action mStopAction;
31 | protected Notification.Builder mBuilder;
32 |
33 | public Notifications(Context context) {
34 | super(context);
35 | if (Build.VERSION.SDK_INT >= O) {
36 | createNotificationChannel();
37 | }
38 | }
39 |
40 | public void recording(long timeMs) {
41 | if (SystemClock.elapsedRealtime() - mLastFiredTime < 1000) {
42 | return;
43 | }
44 | Notification notification = getBuilder()
45 | .setContentText("Length: " + DateUtils.formatElapsedTime(timeMs / 1000))
46 | .build();
47 | getNotificationManager().notify(getId(), notification);
48 | mLastFiredTime = SystemClock.elapsedRealtime();
49 | }
50 |
51 | protected Notification.Builder getBuilder() {
52 | if (mBuilder == null) {
53 | Notification.Builder builder = new Notification.Builder(this)
54 | .setContentTitle("Recording...")
55 | .setOngoing(true)
56 | .setLocalOnly(true)
57 | .setOnlyAlertOnce(true)
58 | .addAction(stopAction())
59 | .setWhen(System.currentTimeMillis())
60 | .setSmallIcon(R.drawable.ic_stat_recording);
61 | if (Build.VERSION.SDK_INT >= O) {
62 | builder.setChannelId(getChannelId())
63 | .setUsesChronometer(true);
64 | }
65 | mBuilder = builder;
66 | }
67 | return mBuilder;
68 | }
69 |
70 | @TargetApi(O)
71 | protected void createNotificationChannel() {
72 | NotificationChannel channel =
73 | new NotificationChannel(getChannelId(), getChannelName(), NotificationManager.IMPORTANCE_LOW);
74 | channel.setShowBadge(false);
75 | getNotificationManager().createNotificationChannel(channel);
76 | }
77 |
78 | protected Notification.Action stopAction() {
79 | if (mStopAction == null) {
80 | Intent intent = new Intent(ACTION_STOP);
81 | PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1,
82 | intent, PendingIntent.FLAG_ONE_SHOT);
83 | mStopAction = new Notification.Action(android.R.drawable.ic_media_pause, "Stop", pendingIntent);
84 | }
85 | return mStopAction;
86 | }
87 |
88 | public void clear() {
89 | mLastFiredTime = 0;
90 | mBuilder = null;
91 | mStopAction = null;
92 | getNotificationManager().cancelAll();
93 | }
94 |
95 | protected NotificationManager getNotificationManager() {
96 | if (mManager == null) {
97 | mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
98 | }
99 | return mManager;
100 | }
101 |
102 | protected int getId(){
103 | return 0x1fff;
104 | }
105 |
106 | protected String getChannelId(){
107 | return "Recording";
108 | }
109 |
110 | protected String getChannelName(){
111 | return "Screen Recorder Notifications";
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/screenrecorder/src/main/java/com/ykbjson/lib/screenrecorder/VideoEncoder.java:
--------------------------------------------------------------------------------
1 | package com.ykbjson.lib.screenrecorder;
2 |
3 | import android.media.MediaCodec;
4 | import android.media.MediaFormat;
5 | import android.util.Log;
6 | import android.view.Surface;
7 |
8 | import java.util.Objects;
9 |
10 | /**
11 | * Description:视频编码器
12 | *
13 | * Creator:yankebin
14 | *
15 | * CreatedAt:2019-07-29
16 | */
17 | class VideoEncoder extends BaseEncoder {
18 | private static final boolean VERBOSE = false;
19 | private VideoEncodeConfig mConfig;
20 | private Surface mSurface;
21 |
22 |
23 | VideoEncoder(VideoEncodeConfig config) {
24 | super(config.codecName);
25 | this.mConfig = config;
26 | }
27 |
28 | @Override
29 | protected void onEncoderConfigured(MediaCodec encoder) {
30 | mSurface = encoder.createInputSurface();
31 | if (VERBOSE) Log.i("@@", "VideoEncoder create input surface: " + mSurface);
32 | }
33 |
34 | @Override
35 | protected MediaFormat createMediaFormat() {
36 | return mConfig.toFormat();
37 | }
38 |
39 | /**
40 | * @throws NullPointerException if prepare() not call
41 | */
42 | Surface getInputSurface() {
43 | return Objects.requireNonNull(mSurface, "doesn't prepare()");
44 | }
45 |
46 | @Override
47 | public void release() {
48 | if (mSurface != null) {
49 | mSurface.release();
50 | mSurface = null;
51 | }
52 | super.release();
53 | }
54 |
55 | VideoEncodeConfig getConfig() {
56 | return mConfig;
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/screenrecorder/src/main/res/drawable-hdpi/ic_stat_recording.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javaertj/simpledlna/b23c824fc83b1b1d1fa337b52301aa41e9a37526/screenrecorder/src/main/res/drawable-hdpi/ic_stat_recording.png
--------------------------------------------------------------------------------
/screenrecorder/src/main/res/drawable-mdpi/ic_stat_recording.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javaertj/simpledlna/b23c824fc83b1b1d1fa337b52301aa41e9a37526/screenrecorder/src/main/res/drawable-mdpi/ic_stat_recording.png
--------------------------------------------------------------------------------
/screenrecorder/src/main/res/drawable-xhdpi/ic_stat_recording.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javaertj/simpledlna/b23c824fc83b1b1d1fa337b52301aa41e9a37526/screenrecorder/src/main/res/drawable-xhdpi/ic_stat_recording.png
--------------------------------------------------------------------------------
/screenrecorder/src/main/res/drawable-xxhdpi/ic_stat_recording.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/javaertj/simpledlna/b23c824fc83b1b1d1fa337b52301aa41e9a37526/screenrecorder/src/main/res/drawable-xxhdpi/ic_stat_recording.png
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':screening', ':webserver', ':simplepermission', ':screenrecorder', ':rtmplibs', ':nginxserver'
2 |
--------------------------------------------------------------------------------
/simplepermission/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | .idea
3 | /.idea
--------------------------------------------------------------------------------
/simplepermission/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 |
4 | android {
5 | compileSdkVersion rootProject.ext.compileSdkVersion
6 |
7 | defaultConfig {
8 | minSdkVersion rootProject.ext.minSdkVersion
9 | targetSdkVersion rootProject.ext.targetSdkVersion
10 | versionCode rootProject.ext.versionCode
11 | versionName rootProject.ext.versionName
12 | }
13 | lintOptions {
14 | abortOnError false
15 | }
16 | }
17 |
18 | dependencies {
19 | implementation fileTree(dir: 'libs', include: ['*.jar'])
20 | implementation "androidx.appcompat:appcompat:$rootProject.ext.supportLibraryVersion"
21 | implementation "io.reactivex.rxjava2:rxandroid:$rootProject.ext.rxAndroidVersion"
22 | }
23 |
--------------------------------------------------------------------------------
/simplepermission/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/simplepermission/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 | String
back
38 | * to its enum value.
39 | */
40 | public enum Method {
41 | GET,
42 | PUT,
43 | POST,
44 | DELETE,
45 | HEAD,
46 | OPTIONS,
47 | TRACE,
48 | CONNECT,
49 | PATCH,
50 | PROPFIND,
51 | PROPPATCH,
52 | MKCOL,
53 | MOVE,
54 | COPY,
55 | LOCK,
56 | UNLOCK,
57 | NOTIFY,
58 | SUBSCRIBE;
59 |
60 | public static Method lookup(String method) {
61 | if (method == null)
62 | return null;
63 |
64 | try {
65 | return valueOf(method);
66 | } catch (IllegalArgumentException e) {
67 | // TODO: Log it?
68 | return null;
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/webserver/src/main/java/org/protocols/http/response/ChunkedOutputStream.java:
--------------------------------------------------------------------------------
1 | package org.protocols.http.response;
2 |
3 | /*
4 | * #%L
5 | * NanoHttpd-Core
6 | * %%
7 | * Copyright (C) 2012 - 2016 nanohttpd
8 | * %%
9 | * Redistribution and use in source and binary forms, with or without modification,
10 | * are permitted provided that the following conditions are met:
11 | *
12 | * 1. Redistributions of source code must retain the above copyright notice, this
13 | * list of conditions and the following disclaimer.
14 | *
15 | * 2. Redistributions in binary form must reproduce the above copyright notice,
16 | * this list of conditions and the following disclaimer in the documentation
17 | * and/or other materials provided with the distribution.
18 | *
19 | * 3. Neither the name of the nanohttpd nor the names of its contributors
20 | * may be used to endorse or promote products derived from this software without
21 | * specific prior written permission.
22 | *
23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32 | * OF THE POSSIBILITY OF SUCH DAMAGE.
33 | * #L%
34 | */
35 |
36 | import java.io.FilterOutputStream;
37 | import java.io.IOException;
38 | import java.io.OutputStream;
39 |
40 | /**
41 | * Output stream that will automatically send every write to the wrapped
42 | * OutputStream according to chunked transfer:
43 | * http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.6.1
44 | */
45 | public class ChunkedOutputStream extends FilterOutputStream {
46 |
47 | public ChunkedOutputStream(OutputStream out) {
48 | super(out);
49 | }
50 |
51 | @Override
52 | public void write(int b) throws IOException {
53 | byte[] data = {
54 | (byte) b
55 | };
56 | write(data, 0, 1);
57 | }
58 |
59 | @Override
60 | public void write(byte[] b) throws IOException {
61 | write(b, 0, b.length);
62 | }
63 |
64 | @Override
65 | public void write(byte[] b, int off, int len) throws IOException {
66 | if (len == 0)
67 | return;
68 | out.write(String.format("%x\r\n", len).getBytes());
69 | out.write(b, off, len);
70 | out.write("\r\n".getBytes());
71 | }
72 |
73 | public void finish() throws IOException {
74 | out.write("0\r\n\r\n".getBytes());
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/webserver/src/main/java/org/protocols/http/response/IStatus.java:
--------------------------------------------------------------------------------
1 | package org.protocols.http.response;
2 |
3 | /*
4 | * #%L
5 | * NanoHttpd-Core
6 | * %%
7 | * Copyright (C) 2012 - 2016 nanohttpd
8 | * %%
9 | * Redistribution and use in source and binary forms, with or without modification,
10 | * are permitted provided that the following conditions are met:
11 | *
12 | * 1. Redistributions of source code must retain the above copyright notice, this
13 | * list of conditions and the following disclaimer.
14 | *
15 | * 2. Redistributions in binary form must reproduce the above copyright notice,
16 | * this list of conditions and the following disclaimer in the documentation
17 | * and/or other materials provided with the distribution.
18 | *
19 | * 3. Neither the name of the nanohttpd nor the names of its contributors
20 | * may be used to endorse or promote products derived from this software without
21 | * specific prior written permission.
22 | *
23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32 | * OF THE POSSIBILITY OF SUCH DAMAGE.
33 | * #L%
34 | */
35 |
36 | public interface IStatus {
37 |
38 | String getDescription();
39 |
40 | int getRequestStatus();
41 | }
42 |
--------------------------------------------------------------------------------
/webserver/src/main/java/org/protocols/http/response/Status.java:
--------------------------------------------------------------------------------
1 | //package org.nanohttpd.protocols.http.response;
2 | package org.protocols.http.response;
3 | /*
4 | * #%L
5 | * NanoHttpd-Core
6 | * %%
7 | * Copyright (C) 2012 - 2016 nanohttpd
8 | * %%
9 | * Redistribution and use in source and binary forms, with or without modification,
10 | * are permitted provided that the following conditions are met:
11 | *
12 | * 1. Redistributions of source code must retain the above copyright notice, this
13 | * list of conditions and the following disclaimer.
14 | *
15 | * 2. Redistributions in binary form must reproduce the above copyright notice,
16 | * this list of conditions and the following disclaimer in the documentation
17 | * and/or other materials provided with the distribution.
18 | *
19 | * 3. Neither the name of the nanohttpd nor the names of its contributors
20 | * may be used to endorse or promote products derived from this software without
21 | * specific prior written permission.
22 | *
23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32 | * OF THE POSSIBILITY OF SUCH DAMAGE.
33 | * #L%
34 | */
35 |
36 | /**
37 | * Some HTTP response status codes
38 | */
39 | public enum Status implements IStatus {
40 | SWITCH_PROTOCOL(101, "Switching Protocols"),
41 |
42 | OK(200, "OK"),
43 | CREATED(201, "Created"),
44 | ACCEPTED(202, "Accepted"),
45 | NO_CONTENT(204, "No Content"),
46 | PARTIAL_CONTENT(206, "Partial Content"),
47 | MULTI_STATUS(207, "Multi-Status"),
48 |
49 | REDIRECT(301, "Moved Permanently"),
50 | /**
51 | * Many user agents mishandle 302 in ways that violate the RFC1945 spec
52 | * (i.e., redirect a POST to a GET). 303 and 307 were added in RFC2616 to
53 | * address this. You should prefer 303 and 307 unless the calling user agent
54 | * does not support 303 and 307 functionality
55 | */
56 | @Deprecated
57 | FOUND(302, "Found"),
58 | REDIRECT_SEE_OTHER(303, "See Other"),
59 | NOT_MODIFIED(304, "Not Modified"),
60 | TEMPORARY_REDIRECT(307, "Temporary Redirect"),
61 |
62 | BAD_REQUEST(400, "Bad Request"),
63 | UNAUTHORIZED(401, "Unauthorized"),
64 | FORBIDDEN(403, "Forbidden"),
65 | NOT_FOUND(404, "Not Found"),
66 | METHOD_NOT_ALLOWED(405, "Method Not Allowed"),
67 | NOT_ACCEPTABLE(406, "Not Acceptable"),
68 | REQUEST_TIMEOUT(408, "Request Timeout"),
69 | CONFLICT(409, "Conflict"),
70 | GONE(410, "Gone"),
71 | LENGTH_REQUIRED(411, "Length Required"),
72 | PRECONDITION_FAILED(412, "Precondition Failed"),
73 | PAYLOAD_TOO_LARGE(413, "Payload Too Large"),
74 | UNSUPPORTED_MEDIA_TYPE(415, "Unsupported Media Type"),
75 | RANGE_NOT_SATISFIABLE(416, "Requested Range Not Satisfiable"),
76 | EXPECTATION_FAILED(417, "Expectation Failed"),
77 | TOO_MANY_REQUESTS(429, "Too Many Requests"),
78 |
79 | INTERNAL_ERROR(500, "Internal Server Error"),
80 | NOT_IMPLEMENTED(501, "Not Implemented"),
81 | SERVICE_UNAVAILABLE(503, "Service Unavailable"),
82 | UNSUPPORTED_HTTP_VERSION(505, "HTTP Version Not Supported");
83 |
84 | private final int requestStatus;
85 |
86 | private final String description;
87 |
88 | Status(int requestStatus, String description) {
89 | this.requestStatus = requestStatus;
90 | this.description = description;
91 | }
92 |
93 | public static Status lookup(int requestStatus) {
94 | for (Status status : Status.values()) {
95 | if (status.getRequestStatus() == requestStatus) {
96 | return status;
97 | }
98 | }
99 | return null;
100 | }
101 |
102 | @Override
103 | public String getDescription() {
104 | return "" + this.requestStatus + " " + this.description;
105 | }
106 |
107 | @Override
108 | public int getRequestStatus() {
109 | return this.requestStatus;
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/webserver/src/main/java/org/protocols/http/sockets/DefaultServerSocketFactory.java:
--------------------------------------------------------------------------------
1 | package org.protocols.http.sockets;
2 |
3 | /*
4 | * #%L
5 | * NanoHttpd-Core
6 | * %%
7 | * Copyright (C) 2012 - 2016 nanohttpd
8 | * %%
9 | * Redistribution and use in source and binary forms, with or without modification,
10 | * are permitted provided that the following conditions are met:
11 | *
12 | * 1. Redistributions of source code must retain the above copyright notice, this
13 | * list of conditions and the following disclaimer.
14 | *
15 | * 2. Redistributions in binary form must reproduce the above copyright notice,
16 | * this list of conditions and the following disclaimer in the documentation
17 | * and/or other materials provided with the distribution.
18 | *
19 | * 3. Neither the name of the nanohttpd nor the names of its contributors
20 | * may be used to endorse or promote products derived from this software without
21 | * specific prior written permission.
22 | *
23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 | * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32 | * OF THE POSSIBILITY OF SUCH DAMAGE.
33 | * #L%
34 | */
35 |
36 | import java.io.IOException;
37 | import java.net.ServerSocket;
38 |
39 | import org.util.IFactoryThrowing;
40 |
41 | /**
42 | * Creates a normal ServerSocket for TCP connections
43 | */
44 | public class DefaultServerSocketFactory implements IFactoryThrowingFile.createTempFile()
in the
48 | * directory specified.
49 | * java.io.tmpdir
points to). Files are added to an internal list,
49 | * and deleted when no longer needed (that is, when clear()
is
50 | * invoked at the end of processing a request).
51 | *