diff options
author | Xiao Hang <rocking@google.com> | 2016-07-25 14:59:43 -0700 |
---|---|---|
committer | Xiao Hang <rocking@google.com> | 2016-08-03 14:47:10 -0700 |
commit | 239d6ea299f812bd6a4fe9f5546b107aee753761 (patch) | |
tree | c8b92de26e43bbb5da8130f6ca58568f5c4740a0 | |
parent | 7d464fcb0214235130efa10d464eea3a0a29a360 (diff) | |
download | grpc-grpc-java-239d6ea299f812bd6a4fe9f5546b107aee753761.tar.gz |
Add android route guide example and move helloworld example to its own dir
42 files changed, 1144 insertions, 0 deletions
diff --git a/examples/android/.gitignore b/examples/android/helloworld/.gitignore index 6345b76a4..6345b76a4 100644 --- a/examples/android/.gitignore +++ b/examples/android/helloworld/.gitignore diff --git a/examples/android/README.md b/examples/android/helloworld/README.md index b5be842eb..b5be842eb 100644 --- a/examples/android/README.md +++ b/examples/android/helloworld/README.md diff --git a/examples/android/app/build.gradle b/examples/android/helloworld/app/build.gradle index 43a0fd5cd..43a0fd5cd 100644 --- a/examples/android/app/build.gradle +++ b/examples/android/helloworld/app/build.gradle diff --git a/examples/android/app/proguard-rules.pro b/examples/android/helloworld/app/proguard-rules.pro index 3b2e11a79..3b2e11a79 100644 --- a/examples/android/app/proguard-rules.pro +++ b/examples/android/helloworld/app/proguard-rules.pro diff --git a/examples/android/app/src/main/AndroidManifest.xml b/examples/android/helloworld/app/src/main/AndroidManifest.xml index 8c40f1168..8c40f1168 100644 --- a/examples/android/app/src/main/AndroidManifest.xml +++ b/examples/android/helloworld/app/src/main/AndroidManifest.xml diff --git a/examples/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java b/examples/android/helloworld/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java index 85e86eab8..85e86eab8 100644 --- a/examples/android/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java +++ b/examples/android/helloworld/app/src/main/java/io/grpc/helloworldexample/HelloworldActivity.java diff --git a/examples/android/app/src/main/proto/helloworld.proto b/examples/android/helloworld/app/src/main/proto/helloworld.proto index 0bee1fcfc..0bee1fcfc 100644 --- a/examples/android/app/src/main/proto/helloworld.proto +++ b/examples/android/helloworld/app/src/main/proto/helloworld.proto diff --git a/examples/android/app/src/main/res/layout/activity_helloworld.xml b/examples/android/helloworld/app/src/main/res/layout/activity_helloworld.xml index 7627079c9..7627079c9 100644 --- a/examples/android/app/src/main/res/layout/activity_helloworld.xml +++ b/examples/android/helloworld/app/src/main/res/layout/activity_helloworld.xml diff --git a/examples/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/android/helloworld/app/src/main/res/mipmap-hdpi/ic_launcher.png Binary files differindex cde69bccc..cde69bccc 100644 --- a/examples/android/app/src/main/res/mipmap-hdpi/ic_launcher.png +++ b/examples/android/helloworld/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/examples/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/android/helloworld/app/src/main/res/mipmap-mdpi/ic_launcher.png Binary files differindex c133a0cbd..c133a0cbd 100644 --- a/examples/android/app/src/main/res/mipmap-mdpi/ic_launcher.png +++ b/examples/android/helloworld/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/examples/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/android/helloworld/app/src/main/res/mipmap-xhdpi/ic_launcher.png Binary files differindex bfa42f0e7..bfa42f0e7 100644 --- a/examples/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png +++ b/examples/android/helloworld/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/examples/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/android/helloworld/app/src/main/res/mipmap-xxhdpi/ic_launcher.png Binary files differindex 324e72cdd..324e72cdd 100644 --- a/examples/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png +++ b/examples/android/helloworld/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/examples/android/app/src/main/res/values/strings.xml b/examples/android/helloworld/app/src/main/res/values/strings.xml index 64cb312d5..64cb312d5 100644 --- a/examples/android/app/src/main/res/values/strings.xml +++ b/examples/android/helloworld/app/src/main/res/values/strings.xml diff --git a/examples/android/build.gradle b/examples/android/helloworld/build.gradle index 493f43970..493f43970 100644 --- a/examples/android/build.gradle +++ b/examples/android/helloworld/build.gradle diff --git a/examples/android/gradle/wrapper/gradle-wrapper.jar b/examples/android/helloworld/gradle/wrapper/gradle-wrapper.jar Binary files differindex 5ccda13e9..5ccda13e9 100644 --- a/examples/android/gradle/wrapper/gradle-wrapper.jar +++ b/examples/android/helloworld/gradle/wrapper/gradle-wrapper.jar diff --git a/examples/android/gradle/wrapper/gradle-wrapper.properties b/examples/android/helloworld/gradle/wrapper/gradle-wrapper.properties index ae20da0b8..ae20da0b8 100644 --- a/examples/android/gradle/wrapper/gradle-wrapper.properties +++ b/examples/android/helloworld/gradle/wrapper/gradle-wrapper.properties diff --git a/examples/android/gradlew b/examples/android/helloworld/gradlew index 27309d923..27309d923 100755 --- a/examples/android/gradlew +++ b/examples/android/helloworld/gradlew diff --git a/examples/android/gradlew.bat b/examples/android/helloworld/gradlew.bat index f6d5974e7..f6d5974e7 100644 --- a/examples/android/gradlew.bat +++ b/examples/android/helloworld/gradlew.bat diff --git a/examples/android/settings.gradle b/examples/android/helloworld/settings.gradle index e7b4def49..e7b4def49 100644 --- a/examples/android/settings.gradle +++ b/examples/android/helloworld/settings.gradle diff --git a/examples/android/routeguide/.gitignore b/examples/android/routeguide/.gitignore new file mode 100644 index 000000000..6345b76a4 --- /dev/null +++ b/examples/android/routeguide/.gitignore @@ -0,0 +1,21 @@ +.gradle +/local.properties +/gradle.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +.idea/ + +*.iml +*.apk +*.ap_ +*.dex +*.class +bin/ +gen/ +.gradle/ +/*/build/ +local.properties +proguard/ +*.log diff --git a/examples/android/app/.gitignore b/examples/android/routeguide/app/.gitignore index 796b96d1c..796b96d1c 100644 --- a/examples/android/app/.gitignore +++ b/examples/android/routeguide/app/.gitignore diff --git a/examples/android/routeguide/app/build.gradle b/examples/android/routeguide/app/build.gradle new file mode 100644 index 000000000..806fbc41a --- /dev/null +++ b/examples/android/routeguide/app/build.gradle @@ -0,0 +1,67 @@ +apply plugin: 'com.android.application' +apply plugin: 'com.google.protobuf' + +android { + compileSdkVersion 23 + buildToolsVersion "24.0.0" + + defaultConfig { + applicationId "io.grpc.routeguideexample" + minSdkVersion 23 + targetSdkVersion 23 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + lintOptions { + disable 'InvalidPackage' + } +} + +protobuf { + protoc { + artifact = 'com.google.protobuf:protoc:3.0.0-beta-3' + } + plugins { + grpc { + artifact = 'io.grpc:protoc-gen-grpc-java:1.1.0-SNAPSHOT' // CURRENT_GRPC_VERSION + } + } + generateProtoTasks { + all().each { task -> + task.builtins { + // Javanano is installed by default, but needs to be removed to use protobuf lite.. + remove javanano + java { + // Options added to --java_out + option 'lite' + } + } + + task.plugins { + grpc { + // Options added to --grpc_out + option 'lite' + } + } + } + } +} + +dependencies { + compile 'com.android.support:appcompat-v7:23.+' + compile 'com.google.code.findbugs:jsr305:3.0.0' + compile 'com.google.guava:guava:18.0' + compile 'com.squareup.okhttp:okhttp:2.2.0' + + // You need to build grpc-java to obtain these libraries below. + compile 'io.grpc:grpc-okhttp:1.1.0-SNAPSHOT' // CURRENT_GRPC_VERSION + compile 'io.grpc:grpc-protobuf-lite:1.1.0-SNAPSHOT' // CURRENT_GRPC_VERSION + compile 'io.grpc:grpc-stub:1.1.0-SNAPSHOT' // CURRENT_GRPC_VERSION + compile 'javax.annotation:javax.annotation-api:1.2' +} diff --git a/examples/android/routeguide/app/proguard-rules.pro b/examples/android/routeguide/app/proguard-rules.pro new file mode 100644 index 000000000..34ff0b3a7 --- /dev/null +++ b/examples/android/routeguide/app/proguard-rules.pro @@ -0,0 +1,15 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /usr/local/google/home/rocking/Android/Sdk/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: + +-dontwarn sun.misc.Unsafe +-dontwarn com.google.common.** +-dontwarn okio.** + diff --git a/examples/android/routeguide/app/src/main/AndroidManifest.xml b/examples/android/routeguide/app/src/main/AndroidManifest.xml new file mode 100644 index 000000000..d557afc08 --- /dev/null +++ b/examples/android/routeguide/app/src/main/AndroidManifest.xml @@ -0,0 +1,22 @@ +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="io.grpc.routeguideexample"> + + <uses-permission android:name="android.permission.INTERNET" /> + + <application android:allowBackup="true" + android:label="@string/app_name" + android:icon="@mipmap/ic_launcher" + android:supportsRtl="true" + android:theme="@style/AppTheme"> + <activity + android:name=".RouteGuideActivity" + android:label="@string/app_name" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + </application> + +</manifest> diff --git a/examples/android/routeguide/app/src/main/java/io/grpc/routeguideexample/RouteGuideActivity.java b/examples/android/routeguide/app/src/main/java/io/grpc/routeguideexample/RouteGuideActivity.java new file mode 100644 index 000000000..432e338ff --- /dev/null +++ b/examples/android/routeguide/app/src/main/java/io/grpc/routeguideexample/RouteGuideActivity.java @@ -0,0 +1,432 @@ +/* + * Copyright 2016, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.grpc.routeguideexample; + +import android.content.Context; +import android.os.AsyncTask; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.text.TextUtils; +import android.text.method.ScrollingMovementMethod; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import io.grpc.Status; +import io.grpc.StatusRuntimeException; +import io.grpc.routeguideexample.RouteGuideGrpc.RouteGuideBlockingStub; +import io.grpc.routeguideexample.RouteGuideGrpc.RouteGuideStub; +import io.grpc.stub.StreamObserver; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Random; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class RouteGuideActivity extends AppCompatActivity { + private static final Logger logger = Logger.getLogger(RouteGuideActivity.class.getName()); + private EditText mHostEdit; + private EditText mPortEdit; + private Button mStartRouteGuideButton; + private Button mExitRouteGuideButton; + private Button mGetFeatureButton; + private Button mListFeaturesButton; + private Button mRecordRouteButton; + private Button mRouteChatButton; + private TextView mResultText; + + private ManagedChannel mChannel; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_routeguide); + mHostEdit = (EditText) findViewById(R.id.host_edit_text); + mPortEdit = (EditText) findViewById(R.id.port_edit_text); + mStartRouteGuideButton = (Button) findViewById(R.id.start_route_guide_button); + mExitRouteGuideButton = (Button) findViewById(R.id.exit_route_guide_button); + mGetFeatureButton = (Button) findViewById(R.id.get_feature_button); + mListFeaturesButton = (Button) findViewById(R.id.list_features_button); + mRecordRouteButton = (Button) findViewById(R.id.record_route_button); + mRouteChatButton = (Button) findViewById(R.id.route_chat_button); + mResultText = (TextView) findViewById(R.id.result_text); + mResultText.setMovementMethod(new ScrollingMovementMethod()); + disableButtons(); + } + + public void startRouteGuide(View view) { + String host = mHostEdit.getText().toString(); + String portStr = mPortEdit.getText().toString(); + int port = TextUtils.isEmpty(portStr) ? 0 : Integer.valueOf(portStr); + ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)) + .hideSoftInputFromWindow(mHostEdit.getWindowToken(), 0); + mChannel = ManagedChannelBuilder.forAddress(host, port).usePlaintext(true).build(); + mHostEdit.setEnabled(false); + mPortEdit.setEnabled(false); + mStartRouteGuideButton.setEnabled(false); + enableButtons(); + } + + public void exitRouteGuide(View view) { + mChannel.shutdown(); + disableButtons(); + mHostEdit.setEnabled(true); + mPortEdit.setEnabled(true); + mStartRouteGuideButton.setEnabled(true); + } + + public void getFeature(View view) { + new GrpcTask(new GetFeatureRunnable()).execute(); + } + + public void listFeatures(View view) { + new GrpcTask(new ListFeaturesRunnable()).execute(); + } + + public void recordRoute(View view) { + new GrpcTask(new RecordRouteRunnable()).execute(); + } + + public void routeChat(View view) { + new GrpcTask(new RouteChatRunnable()).execute(); + } + + private void disableButtons() { + mGetFeatureButton.setEnabled(false); + mListFeaturesButton.setEnabled(false); + mRecordRouteButton.setEnabled(false); + mRouteChatButton.setEnabled(false); + mExitRouteGuideButton.setEnabled(false); + } + + private void enableButtons() { + mExitRouteGuideButton.setEnabled(true); + mGetFeatureButton.setEnabled(true); + mListFeaturesButton.setEnabled(true); + mRecordRouteButton.setEnabled(true); + mRouteChatButton.setEnabled(true); + } + + private class GrpcTask extends AsyncTask<Void, Void, String> { + private final GrpcRunnable mGrpc; + + GrpcTask(GrpcRunnable grpc) { + this.mGrpc = grpc; + } + + @Override + protected void onPreExecute() { + mResultText.setText(""); + disableButtons(); + } + + @Override + protected String doInBackground(Void... nothing) { + try { + String logs = mGrpc.run(RouteGuideGrpc.newBlockingStub(mChannel), + RouteGuideGrpc.newStub(mChannel)); + return "Success!" + System.lineSeparator() + logs; + } catch (Exception e) { + StringWriter sw = new StringWriter(); + PrintWriter pw = new PrintWriter(sw); + e.printStackTrace(pw); + pw.flush(); + return "Failed... : " + System.lineSeparator() + sw; + } + } + + @Override + protected void onPostExecute(String result) { + mResultText.setText(result); + enableButtons(); + } + } + + private interface GrpcRunnable { + /** + * Perform a grpc and return all the logs. + */ + String run(RouteGuideBlockingStub blockingStub, RouteGuideStub asyncStub) throws Exception; + } + + private class GetFeatureRunnable implements GrpcRunnable { + @Override + public String run(RouteGuideBlockingStub blockingStub, RouteGuideStub asyncStub) + throws Exception { + return getFeature(409146138, -746188906, blockingStub); + } + + /** + * Blocking unary call example. Calls getFeature and prints the response. + */ + private String getFeature(int lat, int lon, RouteGuideBlockingStub blockingStub) + throws StatusRuntimeException { + StringBuffer logs = new StringBuffer(); + appendLogs(logs, "*** GetFeature: lat={0} lon={1}", lat, lon); + + Point request = Point.newBuilder().setLatitude(lat).setLongitude(lon).build(); + + Feature feature; + feature = blockingStub.getFeature(request); + if (RouteGuideUtil.exists(feature)) { + appendLogs(logs, "Found feature called \"{0}\" at {1}, {2}", + feature.getName(), + RouteGuideUtil.getLatitude(feature.getLocation()), + RouteGuideUtil.getLongitude(feature.getLocation())); + } else { + appendLogs(logs, "Found no feature at {0}, {1}", + RouteGuideUtil.getLatitude(feature.getLocation()), + RouteGuideUtil.getLongitude(feature.getLocation())); + } + return logs.toString(); + } + } + + private class ListFeaturesRunnable implements GrpcRunnable { + @Override + public String run(RouteGuideBlockingStub blockingStub, RouteGuideStub asyncStub) + throws Exception { + return listFeatures(400000000, -750000000, 420000000, -730000000, blockingStub); + } + + /** + * Blocking server-streaming example. Calls listFeatures with a rectangle of interest. + * Prints each response feature as it arrives. + */ + private String listFeatures(int lowLat, int lowLon, int hiLat, int hiLon, + RouteGuideBlockingStub blockingStub) throws StatusRuntimeException { + StringBuffer logs = new StringBuffer("Result: "); + appendLogs(logs, "*** ListFeatures: lowLat={0} lowLon={1} hiLat={2} hiLon={3}", + lowLat, lowLon, hiLat, hiLon); + + Rectangle request = Rectangle.newBuilder() + .setLo(Point.newBuilder().setLatitude(lowLat).setLongitude(lowLon).build()) + .setHi(Point.newBuilder().setLatitude(hiLat).setLongitude(hiLon).build()) + .build(); + Iterator<Feature> features; + features = blockingStub.listFeatures(request); + + while (features.hasNext()) { + Feature feature = features.next(); + appendLogs(logs, feature.toString()); + } + return logs.toString(); + } + } + + private class RecordRouteRunnable implements GrpcRunnable { + private Throwable failed; + + @Override + public String run(RouteGuideBlockingStub blockingStub, RouteGuideStub asyncStub) + throws Exception { + List<Point> points = new ArrayList<Point>(); + points.add(Point.newBuilder() + .setLatitude(407838351).setLongitude(-746143763).build()); + points.add(Point.newBuilder() + .setLatitude(408122808).setLongitude(-743999179).build()); + points.add(Point.newBuilder() + .setLatitude(413628156).setLongitude(-749015468).build()); + return recordRoute(points, 5, asyncStub); + } + + /** + * Async client-streaming example. Sends {@code numPoints} randomly chosen points from + * {@code features} with a variable delay in between. Prints the statistics when they are + * sent from the server. + */ + private String recordRoute(List<Point> points, int numPoints, RouteGuideStub asyncStub) + throws InterruptedException, RuntimeException { + final StringBuffer logs = new StringBuffer(); + appendLogs(logs, "*** RecordRoute"); + + final CountDownLatch finishLatch = new CountDownLatch(1); + StreamObserver<RouteSummary> responseObserver = new StreamObserver<RouteSummary>() { + @Override + public void onNext(RouteSummary summary) { + appendLogs(logs, "Finished trip with {0} points. Passed {1} features. " + + "Travelled {2} meters. It took {3} seconds.", summary.getPointCount(), + summary.getFeatureCount(), summary.getDistance(), + summary.getElapsedTime()); + } + + @Override + public void onError(Throwable t) { + failed = t; + finishLatch.countDown(); + } + + @Override + public void onCompleted() { + appendLogs(logs, "Finished RecordRoute"); + finishLatch.countDown(); + } + }; + + StreamObserver<Point> requestObserver = asyncStub.recordRoute(responseObserver); + try { + // Send numPoints points randomly selected from the points list. + Random rand = new Random(); + for (int i = 0; i < numPoints; ++i) { + int index = rand.nextInt(points.size()); + Point point = points.get(index); + appendLogs(logs, "Visiting point {0}, {1}", RouteGuideUtil.getLatitude(point), + RouteGuideUtil.getLongitude(point)); + requestObserver.onNext(point); + // Sleep for a bit before sending the next one. + Thread.sleep(rand.nextInt(1000) + 500); + if (finishLatch.getCount() == 0) { + // RPC completed or errored before we finished sending. + // Sending further requests won't error, but they will just be thrown away. + break; + } + } + } catch (RuntimeException e) { + // Cancel RPC + requestObserver.onError(e); + throw e; + } + // Mark the end of requests + requestObserver.onCompleted(); + + // Receiving happens asynchronously + if (!finishLatch.await(1, TimeUnit.MINUTES)) { + throw new RuntimeException( + "Could not finish rpc within 1 minute, the server is likely down"); + } + + if (failed != null) { + throw new RuntimeException(failed); + } + return logs.toString(); + } + } + + private class RouteChatRunnable implements GrpcRunnable { + private Throwable failed; + + @Override + public String run(RouteGuideBlockingStub blockingStub, RouteGuideStub asyncStub) + throws Exception { + return routeChat(asyncStub); + } + + /** + * Bi-directional example, which can only be asynchronous. Send some chat messages, and + * print any chat messages that are sent from the server. + */ + private String routeChat(RouteGuideStub asyncStub) throws InterruptedException, + RuntimeException { + final StringBuffer logs = new StringBuffer(); + appendLogs(logs, "*** RouteChat"); + final CountDownLatch finishLatch = new CountDownLatch(1); + StreamObserver<RouteNote> requestObserver = + asyncStub.routeChat(new StreamObserver<RouteNote>() { + @Override + public void onNext(RouteNote note) { + appendLogs(logs, "Got message \"{0}\" at {1}, {2}", note.getMessage(), + note.getLocation().getLatitude(), + note.getLocation().getLongitude()); + } + + @Override + public void onError(Throwable t) { + failed = t; + finishLatch.countDown(); + } + + @Override + public void onCompleted() { + appendLogs(logs,"Finished RouteChat"); + finishLatch.countDown(); + } + }); + + try { + RouteNote[] requests = + {newNote("First message", 0, 0), newNote("Second message", 0, 1), + newNote("Third message", 1, 0), newNote("Fourth message", 1, 1)}; + + for (RouteNote request : requests) { + appendLogs(logs, "Sending message \"{0}\" at {1}, {2}", request.getMessage(), + request.getLocation().getLatitude(), + request.getLocation().getLongitude()); + requestObserver.onNext(request); + } + } catch (RuntimeException e) { + // Cancel RPC + requestObserver.onError(e); + throw e; + } + // Mark the end of requests + requestObserver.onCompleted(); + + // Receiving happens asynchronously + if (!finishLatch.await(1, TimeUnit.MINUTES)) { + throw new RuntimeException( + "Could not finish rpc within 1 minute, the server is likely down"); + } + + if (failed != null) { + throw new RuntimeException(failed); + } + + return logs.toString(); + } + } + + private static void appendLogs(StringBuffer logs, String msg, Object... params) { + if (params.length > 0) { + logs.append(MessageFormat.format(msg, params)); + } else { + logs.append(msg); + } + logs.append(System.lineSeparator()); + } + + private static RouteNote newNote(String message, int lat, int lon) { + return RouteNote.newBuilder().setMessage(message) + .setLocation(Point.newBuilder().setLatitude(lat).setLongitude(lon).build()).build(); + } +} diff --git a/examples/android/routeguide/app/src/main/java/io/grpc/routeguideexample/RouteGuideUtil.java b/examples/android/routeguide/app/src/main/java/io/grpc/routeguideexample/RouteGuideUtil.java new file mode 100644 index 000000000..775f1beb9 --- /dev/null +++ b/examples/android/routeguide/app/src/main/java/io/grpc/routeguideexample/RouteGuideUtil.java @@ -0,0 +1,67 @@ +/* + * Copyright 2015, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.grpc.routeguideexample; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.util.List; + +/** + * Common utilities for the RouteGuide demo. + */ +public class RouteGuideUtil { + private static final double COORD_FACTOR = 1e7; + + /** + * Gets the latitude for the given point. + */ + public static double getLatitude(Point location) { + return location.getLatitude() / COORD_FACTOR; + } + + /** + * Gets the longitude for the given point. + */ + public static double getLongitude(Point location) { + return location.getLongitude() / COORD_FACTOR; + } + + /** + * Indicates whether the given feature exists (i.e. has a valid name). + */ + public static boolean exists(Feature feature) { + return feature != null && !feature.getName().isEmpty(); + } +} diff --git a/examples/android/routeguide/app/src/main/proto/route_guide.proto b/examples/android/routeguide/app/src/main/proto/route_guide.proto new file mode 100644 index 000000000..f765fc5e1 --- /dev/null +++ b/examples/android/routeguide/app/src/main/proto/route_guide.proto @@ -0,0 +1,131 @@ +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +syntax = "proto3"; + +option java_multiple_files = true; +option java_package = "io.grpc.routeguideexample"; +option java_outer_classname = "RouteGuideProto"; +option objc_class_prefix = "RTG"; + +package routeguide; + +// Interface exported by the server. +service RouteGuide { + // A simple RPC. + // + // Obtains the feature at a given position. + // + // A feature with an empty name is returned if there's no feature at the given + // position. + rpc GetFeature(Point) returns (Feature) {} + + // A server-to-client streaming RPC. + // + // Obtains the Features available within the given Rectangle. Results are + // streamed rather than returned at once (e.g. in a response message with a + // repeated field), as the rectangle may cover a large area and contain a + // huge number of features. + rpc ListFeatures(Rectangle) returns (stream Feature) {} + + // A client-to-server streaming RPC. + // + // Accepts a stream of Points on a route being traversed, returning a + // RouteSummary when traversal is completed. + rpc RecordRoute(stream Point) returns (RouteSummary) {} + + // A Bidirectional streaming RPC. + // + // Accepts a stream of RouteNotes sent while a route is being traversed, + // while receiving other RouteNotes (e.g. from other users). + rpc RouteChat(stream RouteNote) returns (stream RouteNote) {} +} + +// Points are represented as latitude-longitude pairs in the E7 representation +// (degrees multiplied by 10**7 and rounded to the nearest integer). +// Latitudes should be in the range +/- 90 degrees and longitude should be in +// the range +/- 180 degrees (inclusive). +message Point { + int32 latitude = 1; + int32 longitude = 2; +} + +// A latitude-longitude rectangle, represented as two diagonally opposite +// points "lo" and "hi". +message Rectangle { + // One corner of the rectangle. + Point lo = 1; + + // The other corner of the rectangle. + Point hi = 2; +} + +// A feature names something at a given point. +// +// If a feature could not be named, the name is empty. +message Feature { + // The name of the feature. + string name = 1; + + // The point where the feature is detected. + Point location = 2; +} + +// Not used in the RPC. Instead, this is here for the form serialized to disk. +message FeatureDatabase { + repeated Feature feature = 1; +} + +// A RouteNote is a message sent while at a given point. +message RouteNote { + // The location from which the message is sent. + Point location = 1; + + // The message to be sent. + string message = 2; +} + +// A RouteSummary is received in response to a RecordRoute rpc. +// +// It contains the number of individual points received, the number of +// detected features, and the total distance covered as the cumulative sum of +// the distance between each point. +message RouteSummary { + // The number of points received. + int32 point_count = 1; + + // The number of known features passed while traversing the route. + int32 feature_count = 2; + + // The distance covered in metres. + int32 distance = 3; + + // The duration of the traversal in seconds. + int32 elapsed_time = 4; +} diff --git a/examples/android/routeguide/app/src/main/res/layout/activity_routeguide.xml b/examples/android/routeguide/app/src/main/res/layout/activity_routeguide.xml new file mode 100644 index 000000000..4b73bf34a --- /dev/null +++ b/examples/android/routeguide/app/src/main/res/layout/activity_routeguide.xml @@ -0,0 +1,81 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".RouteGuideActivity" + android:orientation="vertical" > + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <EditText + android:id="@+id/host_edit_text" + android:layout_weight="2" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:hint="Enter Host" /> + <EditText + android:id="@+id/port_edit_text" + android:layout_weight="1" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:inputType="numberDecimal" + android:hint="Enter Port" /> + </LinearLayout> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal"> + <Button + android:id="@+id/start_route_guide_button" + android:layout_weight="1" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:onClick="startRouteGuide" + android:text="Start Route Guide" /> + <Button + android:id="@+id/exit_route_guide_button" + android:layout_weight="1" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:onClick="exitRouteGuide" + android:text="Exit Route Guide" /> + </LinearLayout> + + <Button + android:id="@+id/get_feature_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:onClick="getFeature" + android:text="Get Feature" /> + + <Button + android:id="@+id/list_features_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:onClick="listFeatures" + android:text="List Features" /> + + <Button + android:id="@+id/record_route_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:onClick="recordRoute" + android:text="Record Route" /> + + <Button + android:id="@+id/route_chat_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:onClick="routeChat" + android:text="Route Chat" /> + + <TextView + android:id="@+id/result_text" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:scrollbars = "vertical" + android:textSize="16sp" /> + +</LinearLayout> diff --git a/examples/android/routeguide/app/src/main/res/mipmap-hdpi/ic_launcher.png b/examples/android/routeguide/app/src/main/res/mipmap-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 000000000..cde69bccc --- /dev/null +++ b/examples/android/routeguide/app/src/main/res/mipmap-hdpi/ic_launcher.png diff --git a/examples/android/routeguide/app/src/main/res/mipmap-mdpi/ic_launcher.png b/examples/android/routeguide/app/src/main/res/mipmap-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 000000000..c133a0cbd --- /dev/null +++ b/examples/android/routeguide/app/src/main/res/mipmap-mdpi/ic_launcher.png diff --git a/examples/android/routeguide/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/examples/android/routeguide/app/src/main/res/mipmap-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 000000000..bfa42f0e7 --- /dev/null +++ b/examples/android/routeguide/app/src/main/res/mipmap-xhdpi/ic_launcher.png diff --git a/examples/android/routeguide/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/examples/android/routeguide/app/src/main/res/mipmap-xxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 000000000..324e72cdd --- /dev/null +++ b/examples/android/routeguide/app/src/main/res/mipmap-xxhdpi/ic_launcher.png diff --git a/examples/android/routeguide/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/examples/android/routeguide/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 000000000..aee44e138 --- /dev/null +++ b/examples/android/routeguide/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/examples/android/routeguide/app/src/main/res/values/colors.xml b/examples/android/routeguide/app/src/main/res/values/colors.xml new file mode 100644 index 000000000..1c10bfe70 --- /dev/null +++ b/examples/android/routeguide/app/src/main/res/values/colors.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="colorPrimary">#3F51B5</color> + <color name="colorPrimaryDark">#303F9F</color> + <color name="colorAccent">#FF4081</color> +</resources> + diff --git a/examples/android/routeguide/app/src/main/res/values/strings.xml b/examples/android/routeguide/app/src/main/res/values/strings.xml new file mode 100644 index 000000000..7b287fc8d --- /dev/null +++ b/examples/android/routeguide/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ +<resources> + <string name="app_name">RouteGuideExample</string> +</resources> diff --git a/examples/android/routeguide/app/src/main/res/values/styles.xml b/examples/android/routeguide/app/src/main/res/values/styles.xml new file mode 100644 index 000000000..7312f6a3b --- /dev/null +++ b/examples/android/routeguide/app/src/main/res/values/styles.xml @@ -0,0 +1,12 @@ +<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> + +</resources> + diff --git a/examples/android/routeguide/build.gradle b/examples/android/routeguide/build.gradle new file mode 100644 index 000000000..187d26b0e --- /dev/null +++ b/examples/android/routeguide/build.gradle @@ -0,0 +1,25 @@ +// 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.1.2' + classpath "com.google.protobuf:protobuf-gradle-plugin:0.7.7" + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + mavenLocal() + } +} + +task clean(type: Delete) { + delete rootProject.buildDir +} diff --git a/examples/android/routeguide/gradle/wrapper/gradle-wrapper.jar b/examples/android/routeguide/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 000000000..5ccda13e9 --- /dev/null +++ b/examples/android/routeguide/gradle/wrapper/gradle-wrapper.jar diff --git a/examples/android/routeguide/gradle/wrapper/gradle-wrapper.properties b/examples/android/routeguide/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 000000000..ae20da0b8 --- /dev/null +++ b/examples/android/routeguide/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Sat May 07 11:11:12 PDT 2016 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-bin.zip diff --git a/examples/android/routeguide/gradlew b/examples/android/routeguide/gradlew new file mode 100755 index 000000000..27309d923 --- /dev/null +++ b/examples/android/routeguide/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# 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 + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +# 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 +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +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" -a "$nonstop" = "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 "$@" diff --git a/examples/android/routeguide/gradlew.bat b/examples/android/routeguide/gradlew.bat new file mode 100644 index 000000000..f6d5974e7 --- /dev/null +++ b/examples/android/routeguide/gradlew.bat @@ -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
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@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=
+
+@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 Windows 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
diff --git a/examples/android/routeguide/settings.gradle b/examples/android/routeguide/settings.gradle new file mode 100644 index 000000000..e7b4def49 --- /dev/null +++ b/examples/android/routeguide/settings.gradle @@ -0,0 +1 @@ +include ':app' |