diff --git a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java index 2e1543321a..926a8ea3c0 100644 --- a/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java +++ b/OsmAnd-api/src/net/osmand/aidlapi/OsmAndCustomizationConstants.java @@ -8,6 +8,7 @@ public interface OsmAndCustomizationConstants { String DRAWER_MAP_MARKERS_ID = DRAWER_ITEM_ID_SCHEME + "map_markers"; String DRAWER_MY_PLACES_ID = DRAWER_ITEM_ID_SCHEME + "my_places"; String DRAWER_SEARCH_ID = DRAWER_ITEM_ID_SCHEME + "search"; + String DRAWER_WEBSERVER_ID = DRAWER_ITEM_ID_SCHEME + "server"; String DRAWER_DIRECTIONS_ID = DRAWER_ITEM_ID_SCHEME + "directions"; String DRAWER_CONFIGURE_MAP_ID = DRAWER_ITEM_ID_SCHEME + "configure_map"; String DRAWER_DOWNLOAD_MAPS_ID = DRAWER_ITEM_ID_SCHEME + "download_maps"; diff --git a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java index c68e1eb3f1..9506fac030 100644 --- a/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java +++ b/OsmAnd/src/net/osmand/plus/activities/MapActivityActions.java @@ -1009,20 +1009,6 @@ public class MapActivityActions implements DialogProvider { }).createItem()); */ - optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.web_server, mapActivity) - .setId("SERVER_ID") - .setIcon(R.drawable.mm_shop_computer) - .setListener(new ItemClickListener() { - @Override - public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { - app.logEvent("drawer_help_open"); - Intent intent = new Intent(mapActivity, ServerActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); - mapActivity.startActivity(intent); - return true; - } - }).createItem()); - optionsMenuHelper.addItem(new ItemBuilder().setTitleId(R.string.shared_string_help, mapActivity) .setId(DRAWER_HELP_ID) .setIcon(R.drawable.ic_action_help) diff --git a/OsmAnd/src/net/osmand/plus/activities/ServerActivity.java b/OsmAnd/src/net/osmand/plus/activities/ServerActivity.java index 87a460ebf2..56acab9945 100644 --- a/OsmAnd/src/net/osmand/plus/activities/ServerActivity.java +++ b/OsmAnd/src/net/osmand/plus/activities/ServerActivity.java @@ -73,7 +73,7 @@ public class ServerActivity extends AppCompatActivity { OsmAndHttpServer.HOSTNAME = getDeviceAddress(); try { server = new OsmAndHttpServer(); - server.setAndroidApplication((OsmandApplication) this.getApplication()); + server.setApplication((OsmandApplication) this.getApplication()); initialized = true; updateTextView("Server started at: http://" + getDeviceAddress() + ":" + OsmAndHttpServer.PORT); } catch (IOException e) { diff --git a/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java b/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java index 6786e78d70..dde29fa110 100644 --- a/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java +++ b/OsmAnd/src/net/osmand/plus/development/OsmandDevelopmentPlugin.java @@ -13,6 +13,7 @@ import net.osmand.plus.R; import net.osmand.plus.Version; import net.osmand.plus.activities.ContributionVersionActivity; import net.osmand.plus.activities.MapActivity; +import net.osmand.plus.activities.ServerActivity; import net.osmand.plus.dashboard.tools.DashFragmentData; import net.osmand.plus.settings.fragments.BaseSettingsFragment; import net.osmand.plus.views.layers.MapInfoLayer; @@ -21,6 +22,7 @@ import net.osmand.plus.views.OsmandMapTileView; import net.osmand.plus.views.mapwidgets.widgets.TextInfoWidget; import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_BUILDS_ID; +import static net.osmand.aidlapi.OsmAndCustomizationConstants.DRAWER_WEBSERVER_ID; public class OsmandDevelopmentPlugin extends OsmandPlugin { @@ -71,8 +73,20 @@ public class OsmandDevelopmentPlugin extends OsmandPlugin { return true; } }).createItem()); - } + helper.addItem(new ContextMenuItem.ItemBuilder().setTitleId(R.string.web_server, mapActivity) + .setId(DRAWER_WEBSERVER_ID) + .setIcon(R.drawable.mm_shop_computer) + .setListener(new ContextMenuAdapter.ItemClickListener() { + @Override + public boolean onContextMenuClick(ArrayAdapter adapter, int itemId, int pos, boolean isChecked, int[] viewCoordinates) { + Intent intent = new Intent(mapActivity, ServerActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); + mapActivity.startActivity(intent); + return true; + } + }).createItem()); + } } @Override diff --git a/OsmAnd/src/net/osmand/plus/server/ApiEndpoint.java b/OsmAnd/src/net/osmand/plus/server/ApiEndpoint.java index 8e0baf71f7..74dd3b03dd 100644 --- a/OsmAnd/src/net/osmand/plus/server/ApiEndpoint.java +++ b/OsmAnd/src/net/osmand/plus/server/ApiEndpoint.java @@ -1,18 +1,10 @@ package net.osmand.plus.server; -import java.util.concurrent.Callable; - import fi.iki.elonen.NanoHTTPD; +import net.osmand.plus.OsmandApplication; -public class ApiEndpoint{ - public String uri = ""; - public ApiCall apiCall; +public interface ApiEndpoint { + NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session); - public NanoHTTPD.Response run(NanoHTTPD.IHTTPSession session){ - return apiCall.call(session); - } - - public interface ApiCall{ - NanoHTTPD.Response call(NanoHTTPD.IHTTPSession session); - } + void setApplication(OsmandApplication application); } diff --git a/OsmAnd/src/net/osmand/plus/server/ApiRouter.java b/OsmAnd/src/net/osmand/plus/server/ApiRouter.java index 7ab90b2aae..53f5febcd5 100644 --- a/OsmAnd/src/net/osmand/plus/server/ApiRouter.java +++ b/OsmAnd/src/net/osmand/plus/server/ApiRouter.java @@ -5,87 +5,29 @@ import android.webkit.MimeTypeMap; import fi.iki.elonen.NanoHTTPD; import net.osmand.PlatformUtil; import net.osmand.plus.OsmandApplication; -import net.osmand.plus.server.endpoints.TileEndpoint; -import net.osmand.util.Algorithms; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse; public class ApiRouter { - private OsmandApplication application; - private final String FOLDER_NAME = "server"; - private final Map endpoints = new HashMap<>(); + private static final String FOLDER_NAME = "server"; private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(ApiRouter.class); - - public ApiRouter() { - initRoutes(); - } + private final Map endpoints = new HashMap<>(); + private OsmandApplication application; public OsmandApplication getApplication() { return application; } - final TileEndpoint tileEndpoint = new TileEndpoint(application); - - private void initRoutes() { - endpoints.put(tileEndpoint.uri, tileEndpoint); - } - public void setApplication(OsmandApplication application) { this.application = application; - tileEndpoint.setApplication(application); - } - - public NanoHTTPD.Response route(NanoHTTPD.IHTTPSession session) { - Log.d("SERVER", "URI: " + session.getUri()); - String uri = session.getUri(); - if (uri.equals("/")) { - return getStatic("/go.html"); + for (String s : endpoints.keySet()) { + endpoints.get(s).setApplication(application); } - if (uri.contains("/scripts/") || - uri.contains("/images/") || - uri.contains("/css/") || - uri.contains("/fonts/") || - uri.contains("/favicon.ico") - ) { - return getStatic(uri); - } - if (isApiUrl(uri)) { - return routeApi(session); - } else { - return getStatic(session.getUri()); - } - } - - private NanoHTTPD.Response routeApi(NanoHTTPD.IHTTPSession session) { - String uri = session.getUri(); - int pathEnd = uri.indexOf("/", 1); - if (pathEnd != -1) { - uri = uri.substring(0, pathEnd); - } - ApiEndpoint endpoint = endpoints.get(uri); - if (endpoint != null) { - return endpoint.apiCall.call(session); - } - return ErrorResponses.response404; - } - - private boolean isApiUrl(String uri) { - for (String endpoint : endpoints.keySet()) { - int stringLength = endpoint.length(); - if (uri.startsWith(endpoint) && - (uri.length() == endpoint.length() || uri.charAt(stringLength) == '/')) { - return true; - } - } - return false; } public NanoHTTPD.Response getStatic(String uri) { @@ -109,6 +51,48 @@ public class ApiRouter { return ErrorResponses.response500; } + public NanoHTTPD.Response route(NanoHTTPD.IHTTPSession session) { + Log.d("SERVER", "URI: " + session.getUri()); + String uri = session.getUri(); + if (uri.equals("/")) { + return getStatic("/go.html"); + } + if (isApiUrl(uri)) { + return routeApi(session); + } + return getStatic(uri); + } + + public void register(String path, ApiEndpoint endpoint) { + endpoint.setApplication(application); + endpoints.put(path, endpoint); + } + + private NanoHTTPD.Response routeApi(NanoHTTPD.IHTTPSession session) { + String uri = session.getUri(); + int pathEnd = uri.indexOf("/", 1); + if (pathEnd != -1) { + uri = uri.substring(0, pathEnd); + } + ApiEndpoint endpoint = endpoints.get(uri); + if (endpoint != null) { + return endpoint.process(session); + } + return ErrorResponses.response404; + } + + private boolean isApiUrl(String uri) { + for (String endpoint : endpoints.keySet()) { + int stringLength = endpoint.length(); + if (uri.startsWith(endpoint) && + (uri.length() == endpoint.length() || uri.charAt(stringLength) == '/')) { + return true; + } + } + return false; + } + + private String parseMimeType(String url) { String type = "text/plain"; if (url.endsWith(".js")) return "text/javascript"; diff --git a/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java b/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java index af08858f2f..a7eec56277 100644 --- a/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java +++ b/OsmAnd/src/net/osmand/plus/server/OsmAndHttpServer.java @@ -1,34 +1,38 @@ package net.osmand.plus.server; +import fi.iki.elonen.NanoHTTPD; import net.osmand.plus.OsmandApplication; +import net.osmand.plus.server.endpoints.TileEndpoint; import java.io.IOException; -import fi.iki.elonen.NanoHTTPD; - public class OsmAndHttpServer extends NanoHTTPD { public static int PORT = 24990; public static String HOSTNAME = "0.0.0.0"; - - private ServerSessionHandler sessionHandler = new ServerSessionHandler(); - private OsmandApplication androidApplication; - - public OsmandApplication getAndroidApplication() { - return androidApplication; - } - - public void setAndroidApplication(OsmandApplication androidApplication) { - this.androidApplication = androidApplication; - sessionHandler.setAndroidApplication(androidApplication); - } + private final ApiRouter router = new ApiRouter(); + private OsmandApplication application; public OsmAndHttpServer() throws IOException { - super(HOSTNAME,PORT); + super(HOSTNAME, PORT); start(NanoHTTPD.SOCKET_READ_TIMEOUT, false); + registerEndpoints(); + } + + public OsmandApplication getApplication() { + return application; + } + + public void setApplication(OsmandApplication application) { + this.application = application; + router.setApplication(application); + } + + private void registerEndpoints() { + router.register("/tile", new TileEndpoint(application)); } @Override public Response serve(IHTTPSession session) { - return sessionHandler.handle(session); + return router.route(session); } } diff --git a/OsmAnd/src/net/osmand/plus/server/ServerSessionHandler.java b/OsmAnd/src/net/osmand/plus/server/ServerSessionHandler.java deleted file mode 100644 index ba4b8c6419..0000000000 --- a/OsmAnd/src/net/osmand/plus/server/ServerSessionHandler.java +++ /dev/null @@ -1,24 +0,0 @@ -package net.osmand.plus.server; - -import net.osmand.plus.OsmandApplication; - -import fi.iki.elonen.NanoHTTPD; - -public class ServerSessionHandler { - private OsmandApplication androidApplication; - - private ApiRouter router = new ApiRouter(); - - public OsmandApplication getAndroidApplication() { - return androidApplication; - } - - public void setAndroidApplication(OsmandApplication androidApplication) { - this.androidApplication = androidApplication; - router.setApplication(androidApplication); - } - - public NanoHTTPD.Response handle(NanoHTTPD.IHTTPSession session) { - return router.route(session); - } -} diff --git a/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java b/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java index 9ffd2f2752..f0a5b598b4 100644 --- a/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java +++ b/OsmAnd/src/net/osmand/plus/server/endpoints/TileEndpoint.java @@ -22,27 +22,30 @@ import java.util.concurrent.*; import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse; -public class TileEndpoint extends ApiEndpoint { +public class TileEndpoint implements ApiEndpoint { + private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class); ExecutorService executor = Executors.newFixedThreadPool(3); Map hashMap = new HashMap<>(); Map map = Collections.synchronizedMap(hashMap); OsmandApplication application; - private static final Log LOG = PlatformUtil.getLog(TileEndpoint.class); public TileEndpoint(OsmandApplication application) { this.application = application; - this.uri = "/tile"; - this.apiCall = new ApiEndpoint.ApiCall() { - @Override - public NanoHTTPD.Response call(NanoHTTPD.IHTTPSession session) { - try { - return tileApiCall(session); - } catch (Exception e) { - LOG.error("Exception", e); - } - return ApiRouter.ErrorResponses.response500; - } - }; + } + + @Override + public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session) { + try { + return tileApiCall(session); + } catch (Exception e) { + LOG.error("Exception", e); + } + return ApiRouter.ErrorResponses.response500; + } + + @Override + public void setApplication(OsmandApplication application) { + this.application = application; } private synchronized NanoHTTPD.Response tileApiCall(NanoHTTPD.IHTTPSession session) { @@ -96,8 +99,4 @@ public class TileEndpoint extends ApiEndpoint { return ApiRouter.ErrorResponses.response500; } } - - public void setApplication(OsmandApplication application) { - this.application = application; - } } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar deleted file mode 100644 index 758de960ec..0000000000 Binary files a/gradle/wrapper/gradle-wrapper.jar and /dev/null differ