• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2016 Google, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * Relicensed from the WTFPL (http://www.wtfpl.net/faq/).
17  */
18 
19 #include "android_util.h"
20 #include <android_native_app_glue.h>
21 #include <cassert>
22 #include <vector>
23 #include <string>
24 #include <sstream>
25 
26 extern "C" {
27 
28 // Convert Intents to arg list, returning argc and argv
29 // Note that this C routine mallocs memory that the caller must free
get_args(struct android_app * app,const char * intent_extra_data_key,const char * appTag,int * count)30 char** get_args(struct android_app* app, const char* intent_extra_data_key, const char* appTag, int* count)
31 {
32     std::vector<std::string> args;
33     JavaVM &vm = *app->activity->vm;
34     JNIEnv *p_env;
35     if (vm.AttachCurrentThread(&p_env, nullptr) != JNI_OK)
36         return nullptr;
37 
38     JNIEnv &env = *p_env;
39     jobject activity = app->activity->clazz;
40     jmethodID get_intent_method = env.GetMethodID(env.GetObjectClass(activity),
41             "getIntent", "()Landroid/content/Intent;");
42     jobject intent = env.CallObjectMethod(activity, get_intent_method);
43     jmethodID get_string_extra_method = env.GetMethodID(env.GetObjectClass(intent),
44             "getStringExtra", "(Ljava/lang/String;)Ljava/lang/String;");
45     jvalue get_string_extra_args;
46     get_string_extra_args.l = env.NewStringUTF(intent_extra_data_key);
47     jstring extra_str = static_cast<jstring>(env.CallObjectMethodA(intent,
48             get_string_extra_method, &get_string_extra_args));
49 
50     std::string args_str;
51     if (extra_str) {
52         const char *extra_utf = env.GetStringUTFChars(extra_str, nullptr);
53         args_str = extra_utf;
54         env.ReleaseStringUTFChars(extra_str, extra_utf);
55         env.DeleteLocalRef(extra_str);
56     }
57 
58     env.DeleteLocalRef(get_string_extra_args.l);
59     env.DeleteLocalRef(intent);
60     vm.DetachCurrentThread();
61 
62     // split args_str
63     std::stringstream ss(args_str);
64     std::string arg;
65     while (std::getline(ss, arg, ' ')) {
66         if (!arg.empty())
67             args.push_back(arg);
68     }
69 
70     // Convert our STL results to C friendly constructs
71     assert(count != nullptr);
72     *count = args.size() + 1;
73     char** vector = (char**) malloc(*count * sizeof(char*));
74     const char* appName = appTag ? appTag : (const char*) "appTag";
75 
76    vector[0] = (char*) malloc(strlen(appName) * sizeof(char));
77    strcpy(vector[0], appName);
78 
79     for (uint32_t i = 0; i < args.size(); i++) {
80         vector[i + 1] = (char*) malloc(strlen(args[i].c_str()) * sizeof(char));
81         strcpy(vector[i + 1], args[i].c_str());
82     }
83 
84     return vector;
85 }
86 
87 } // extern "C"
88