3dphotoshoot

diff src/android/native_glue.c @ 1:7eb73ce46dd0

fucking jni man ... wtf
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 14 May 2015 23:46:56 +0300
parents src/android/android_native_app_glue.c@a4bf2687e406
children cf5964db7ff3
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/android/native_glue.c	Thu May 14 23:46:56 2015 +0300
     1.3 @@ -0,0 +1,457 @@
     1.4 +/*
     1.5 + * Copyright (C) 2010 The Android Open Source Project
     1.6 + *
     1.7 + * Licensed under the Apache License, Version 2.0 (the "License");
     1.8 + * you may not use this file except in compliance with the License.
     1.9 + * You may obtain a copy of the License at
    1.10 + *
    1.11 + *      http://www.apache.org/licenses/LICENSE-2.0
    1.12 + *
    1.13 + * Unless required by applicable law or agreed to in writing, software
    1.14 + * distributed under the License is distributed on an "AS IS" BASIS,
    1.15 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1.16 + * See the License for the specific language governing permissions and
    1.17 + * limitations under the License.
    1.18 + *
    1.19 + */
    1.20 +
    1.21 +#include <jni.h>
    1.22 +
    1.23 +#include <errno.h>
    1.24 +#include <string.h>
    1.25 +#include <unistd.h>
    1.26 +#include <sys/resource.h>
    1.27 +
    1.28 +#include "native_glue.h"
    1.29 +#include <android/log.h>
    1.30 +
    1.31 +#define ACTIVITY_NAME	"com/mutantstargoat/photoshoot3d/MainActivity"
    1.32 +
    1.33 +#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, APP_NAME, __VA_ARGS__))
    1.34 +#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, APP_NAME, __VA_ARGS__))
    1.35 +
    1.36 +/* For debug builds, always enable the debug traces in this library */
    1.37 +#ifndef NDEBUG
    1.38 +#  define LOGV(...)  ((void)__android_log_print(ANDROID_LOG_VERBOSE, APP_NAME, __VA_ARGS__))
    1.39 +#else
    1.40 +#  define LOGV(...)  ((void)0)
    1.41 +#endif
    1.42 +
    1.43 +static void free_saved_state(struct android_app* android_app) {
    1.44 +    pthread_mutex_lock(&android_app->mutex);
    1.45 +    if (android_app->savedState != NULL) {
    1.46 +        free(android_app->savedState);
    1.47 +        android_app->savedState = NULL;
    1.48 +        android_app->savedStateSize = 0;
    1.49 +    }
    1.50 +    pthread_mutex_unlock(&android_app->mutex);
    1.51 +}
    1.52 +
    1.53 +int8_t android_app_read_cmd(struct android_app* android_app) {
    1.54 +    int8_t cmd;
    1.55 +    if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) {
    1.56 +        switch (cmd) {
    1.57 +            case APP_CMD_SAVE_STATE:
    1.58 +                free_saved_state(android_app);
    1.59 +                break;
    1.60 +        }
    1.61 +        return cmd;
    1.62 +    } else {
    1.63 +        LOGE("No data on command pipe!");
    1.64 +    }
    1.65 +    return -1;
    1.66 +}
    1.67 +
    1.68 +static void print_cur_config(struct android_app* android_app) {
    1.69 +    char lang[2], country[2];
    1.70 +    AConfiguration_getLanguage(android_app->config, lang);
    1.71 +    AConfiguration_getCountry(android_app->config, country);
    1.72 +
    1.73 +    LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d "
    1.74 +            "keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d "
    1.75 +            "modetype=%d modenight=%d",
    1.76 +            AConfiguration_getMcc(android_app->config),
    1.77 +            AConfiguration_getMnc(android_app->config),
    1.78 +            lang[0], lang[1], country[0], country[1],
    1.79 +            AConfiguration_getOrientation(android_app->config),
    1.80 +            AConfiguration_getTouchscreen(android_app->config),
    1.81 +            AConfiguration_getDensity(android_app->config),
    1.82 +            AConfiguration_getKeyboard(android_app->config),
    1.83 +            AConfiguration_getNavigation(android_app->config),
    1.84 +            AConfiguration_getKeysHidden(android_app->config),
    1.85 +            AConfiguration_getNavHidden(android_app->config),
    1.86 +            AConfiguration_getSdkVersion(android_app->config),
    1.87 +            AConfiguration_getScreenSize(android_app->config),
    1.88 +            AConfiguration_getScreenLong(android_app->config),
    1.89 +            AConfiguration_getUiModeType(android_app->config),
    1.90 +            AConfiguration_getUiModeNight(android_app->config));
    1.91 +}
    1.92 +
    1.93 +void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
    1.94 +    switch (cmd) {
    1.95 +        case APP_CMD_INPUT_CHANGED:
    1.96 +            LOGV("APP_CMD_INPUT_CHANGED\n");
    1.97 +            pthread_mutex_lock(&android_app->mutex);
    1.98 +            if (android_app->inputQueue != NULL) {
    1.99 +                AInputQueue_detachLooper(android_app->inputQueue);
   1.100 +            }
   1.101 +            android_app->inputQueue = android_app->pendingInputQueue;
   1.102 +            if (android_app->inputQueue != NULL) {
   1.103 +                LOGV("Attaching input queue to looper");
   1.104 +                AInputQueue_attachLooper(android_app->inputQueue,
   1.105 +                        android_app->looper, LOOPER_ID_INPUT, NULL,
   1.106 +                        &android_app->inputPollSource);
   1.107 +            }
   1.108 +            pthread_cond_broadcast(&android_app->cond);
   1.109 +            pthread_mutex_unlock(&android_app->mutex);
   1.110 +            break;
   1.111 +
   1.112 +        case APP_CMD_INIT_WINDOW:
   1.113 +            LOGV("APP_CMD_INIT_WINDOW\n");
   1.114 +            pthread_mutex_lock(&android_app->mutex);
   1.115 +            android_app->window = android_app->pendingWindow;
   1.116 +            pthread_cond_broadcast(&android_app->cond);
   1.117 +            pthread_mutex_unlock(&android_app->mutex);
   1.118 +            break;
   1.119 +
   1.120 +        case APP_CMD_TERM_WINDOW:
   1.121 +            LOGV("APP_CMD_TERM_WINDOW\n");
   1.122 +            pthread_cond_broadcast(&android_app->cond);
   1.123 +            break;
   1.124 +
   1.125 +        case APP_CMD_RESUME:
   1.126 +        case APP_CMD_START:
   1.127 +        case APP_CMD_PAUSE:
   1.128 +        case APP_CMD_STOP:
   1.129 +            LOGV("activityState=%d\n", cmd);
   1.130 +            pthread_mutex_lock(&android_app->mutex);
   1.131 +            android_app->activityState = cmd;
   1.132 +            pthread_cond_broadcast(&android_app->cond);
   1.133 +            pthread_mutex_unlock(&android_app->mutex);
   1.134 +            break;
   1.135 +
   1.136 +        case APP_CMD_CONFIG_CHANGED:
   1.137 +            LOGV("APP_CMD_CONFIG_CHANGED\n");
   1.138 +            AConfiguration_fromAssetManager(android_app->config,
   1.139 +                    android_app->activity->assetManager);
   1.140 +            print_cur_config(android_app);
   1.141 +            break;
   1.142 +
   1.143 +        case APP_CMD_DESTROY:
   1.144 +            LOGV("APP_CMD_DESTROY\n");
   1.145 +            android_app->destroyRequested = 1;
   1.146 +            break;
   1.147 +    }
   1.148 +}
   1.149 +
   1.150 +void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
   1.151 +    switch (cmd) {
   1.152 +        case APP_CMD_TERM_WINDOW:
   1.153 +            LOGV("APP_CMD_TERM_WINDOW\n");
   1.154 +            pthread_mutex_lock(&android_app->mutex);
   1.155 +            android_app->window = NULL;
   1.156 +            pthread_cond_broadcast(&android_app->cond);
   1.157 +            pthread_mutex_unlock(&android_app->mutex);
   1.158 +            break;
   1.159 +
   1.160 +        case APP_CMD_SAVE_STATE:
   1.161 +            LOGV("APP_CMD_SAVE_STATE\n");
   1.162 +            pthread_mutex_lock(&android_app->mutex);
   1.163 +            android_app->stateSaved = 1;
   1.164 +            pthread_cond_broadcast(&android_app->cond);
   1.165 +            pthread_mutex_unlock(&android_app->mutex);
   1.166 +            break;
   1.167 +
   1.168 +        case APP_CMD_RESUME:
   1.169 +            free_saved_state(android_app);
   1.170 +            break;
   1.171 +    }
   1.172 +}
   1.173 +
   1.174 +void app_dummy() {
   1.175 +
   1.176 +}
   1.177 +
   1.178 +static void android_app_destroy(struct android_app* android_app) {
   1.179 +    LOGV("android_app_destroy!");
   1.180 +    free_saved_state(android_app);
   1.181 +    pthread_mutex_lock(&android_app->mutex);
   1.182 +    if (android_app->inputQueue != NULL) {
   1.183 +        AInputQueue_detachLooper(android_app->inputQueue);
   1.184 +    }
   1.185 +    AConfiguration_delete(android_app->config);
   1.186 +    android_app->destroyed = 1;
   1.187 +    pthread_cond_broadcast(&android_app->cond);
   1.188 +    pthread_mutex_unlock(&android_app->mutex);
   1.189 +    // Can't touch android_app object after this.
   1.190 +}
   1.191 +
   1.192 +static void process_input(struct android_app* app, struct android_poll_source* source) {
   1.193 +    AInputEvent* event = NULL;
   1.194 +    while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
   1.195 +        LOGV("New input event: type=%d\n", AInputEvent_getType(event));
   1.196 +        if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
   1.197 +            continue;
   1.198 +        }
   1.199 +        int32_t handled = 0;
   1.200 +        if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
   1.201 +        AInputQueue_finishEvent(app->inputQueue, event, handled);
   1.202 +    }
   1.203 +}
   1.204 +
   1.205 +static void process_cmd(struct android_app* app, struct android_poll_source* source) {
   1.206 +    int8_t cmd = android_app_read_cmd(app);
   1.207 +    android_app_pre_exec_cmd(app, cmd);
   1.208 +    if (app->onAppCmd != NULL) app->onAppCmd(app, cmd);
   1.209 +    android_app_post_exec_cmd(app, cmd);
   1.210 +}
   1.211 +
   1.212 +static void* android_app_entry(void* param) {
   1.213 +    struct android_app* android_app = (struct android_app*)param;
   1.214 +
   1.215 +    android_app->config = AConfiguration_new();
   1.216 +    AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);
   1.217 +
   1.218 +    print_cur_config(android_app);
   1.219 +
   1.220 +    android_app->cmdPollSource.id = LOOPER_ID_MAIN;
   1.221 +    android_app->cmdPollSource.app = android_app;
   1.222 +    android_app->cmdPollSource.process = process_cmd;
   1.223 +    android_app->inputPollSource.id = LOOPER_ID_INPUT;
   1.224 +    android_app->inputPollSource.app = android_app;
   1.225 +    android_app->inputPollSource.process = process_input;
   1.226 +
   1.227 +    ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
   1.228 +    ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL,
   1.229 +            &android_app->cmdPollSource);
   1.230 +    android_app->looper = looper;
   1.231 +
   1.232 +    pthread_mutex_lock(&android_app->mutex);
   1.233 +    android_app->running = 1;
   1.234 +    pthread_cond_broadcast(&android_app->cond);
   1.235 +    pthread_mutex_unlock(&android_app->mutex);
   1.236 +
   1.237 +    android_main(android_app);
   1.238 +
   1.239 +    android_app_destroy(android_app);
   1.240 +    return NULL;
   1.241 +}
   1.242 +
   1.243 +// --------------------------------------------------------------------
   1.244 +// Native activity interaction (called from main thread)
   1.245 +// --------------------------------------------------------------------
   1.246 +
   1.247 +static struct android_app* android_app_create(ANativeActivity* activity,
   1.248 +        void* savedState, size_t savedStateSize) {
   1.249 +	JNIEnv *jni = activity->env;
   1.250 +    struct android_app* android_app = malloc(sizeof(struct android_app));
   1.251 +    memset(android_app, 0, sizeof(struct android_app));
   1.252 +    android_app->activity = activity;
   1.253 +
   1.254 +	{
   1.255 +		jclass foo = (*jni)->FindClass(jni, "java/lang/String");
   1.256 +		if(!foo) {
   1.257 +			LOGE("String class not found!!!!!!\n");
   1.258 +		} else {
   1.259 +			LOGE("Found String class!!!!!!\n");
   1.260 +		}
   1.261 +	}
   1.262 +
   1.263 +	if(!(android_app->activity_class = (*jni)->FindClass(jni, ACTIVITY_NAME))) {
   1.264 +		LOGE("could not find activity: " ACTIVITY_NAME);
   1.265 +		return 0;
   1.266 +	}
   1.267 +
   1.268 +    pthread_mutex_init(&android_app->mutex, NULL);
   1.269 +    pthread_cond_init(&android_app->cond, NULL);
   1.270 +
   1.271 +    if (savedState != NULL) {
   1.272 +        android_app->savedState = malloc(savedStateSize);
   1.273 +        android_app->savedStateSize = savedStateSize;
   1.274 +        memcpy(android_app->savedState, savedState, savedStateSize);
   1.275 +    }
   1.276 +
   1.277 +    int msgpipe[2];
   1.278 +    if (pipe(msgpipe)) {
   1.279 +        LOGE("could not create pipe: %s", strerror(errno));
   1.280 +        return NULL;
   1.281 +    }
   1.282 +    android_app->msgread = msgpipe[0];
   1.283 +    android_app->msgwrite = msgpipe[1];
   1.284 +
   1.285 +    pthread_attr_t attr;
   1.286 +    pthread_attr_init(&attr);
   1.287 +    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   1.288 +    pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
   1.289 +
   1.290 +    // Wait for thread to start.
   1.291 +    pthread_mutex_lock(&android_app->mutex);
   1.292 +    while (!android_app->running) {
   1.293 +        pthread_cond_wait(&android_app->cond, &android_app->mutex);
   1.294 +    }
   1.295 +    pthread_mutex_unlock(&android_app->mutex);
   1.296 +
   1.297 +    return android_app;
   1.298 +}
   1.299 +
   1.300 +static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
   1.301 +    if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
   1.302 +        LOGE("Failure writing android_app cmd: %s\n", strerror(errno));
   1.303 +    }
   1.304 +}
   1.305 +
   1.306 +static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) {
   1.307 +    pthread_mutex_lock(&android_app->mutex);
   1.308 +    android_app->pendingInputQueue = inputQueue;
   1.309 +    android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);
   1.310 +    while (android_app->inputQueue != android_app->pendingInputQueue) {
   1.311 +        pthread_cond_wait(&android_app->cond, &android_app->mutex);
   1.312 +    }
   1.313 +    pthread_mutex_unlock(&android_app->mutex);
   1.314 +}
   1.315 +
   1.316 +static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) {
   1.317 +    pthread_mutex_lock(&android_app->mutex);
   1.318 +    if (android_app->pendingWindow != NULL) {
   1.319 +        android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW);
   1.320 +    }
   1.321 +    android_app->pendingWindow = window;
   1.322 +    if (window != NULL) {
   1.323 +        android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW);
   1.324 +    }
   1.325 +    while (android_app->window != android_app->pendingWindow) {
   1.326 +        pthread_cond_wait(&android_app->cond, &android_app->mutex);
   1.327 +    }
   1.328 +    pthread_mutex_unlock(&android_app->mutex);
   1.329 +}
   1.330 +
   1.331 +static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) {
   1.332 +    pthread_mutex_lock(&android_app->mutex);
   1.333 +    android_app_write_cmd(android_app, cmd);
   1.334 +    while (android_app->activityState != cmd) {
   1.335 +        pthread_cond_wait(&android_app->cond, &android_app->mutex);
   1.336 +    }
   1.337 +    pthread_mutex_unlock(&android_app->mutex);
   1.338 +}
   1.339 +
   1.340 +static void android_app_free(struct android_app* android_app) {
   1.341 +    pthread_mutex_lock(&android_app->mutex);
   1.342 +    android_app_write_cmd(android_app, APP_CMD_DESTROY);
   1.343 +    while (!android_app->destroyed) {
   1.344 +        pthread_cond_wait(&android_app->cond, &android_app->mutex);
   1.345 +    }
   1.346 +    pthread_mutex_unlock(&android_app->mutex);
   1.347 +
   1.348 +    close(android_app->msgread);
   1.349 +    close(android_app->msgwrite);
   1.350 +    pthread_cond_destroy(&android_app->cond);
   1.351 +    pthread_mutex_destroy(&android_app->mutex);
   1.352 +    free(android_app);
   1.353 +}
   1.354 +
   1.355 +static void onDestroy(ANativeActivity* activity) {
   1.356 +    LOGV("Destroy: %p\n", activity);
   1.357 +    android_app_free((struct android_app*)activity->instance);
   1.358 +}
   1.359 +
   1.360 +static void onStart(ANativeActivity* activity) {
   1.361 +    LOGV("Start: %p\n", activity);
   1.362 +    android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START);
   1.363 +}
   1.364 +
   1.365 +static void onResume(ANativeActivity* activity) {
   1.366 +    LOGV("Resume: %p\n", activity);
   1.367 +    android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME);
   1.368 +}
   1.369 +
   1.370 +static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) {
   1.371 +    struct android_app* android_app = (struct android_app*)activity->instance;
   1.372 +    void* savedState = NULL;
   1.373 +
   1.374 +    LOGV("SaveInstanceState: %p\n", activity);
   1.375 +    pthread_mutex_lock(&android_app->mutex);
   1.376 +    android_app->stateSaved = 0;
   1.377 +    android_app_write_cmd(android_app, APP_CMD_SAVE_STATE);
   1.378 +    while (!android_app->stateSaved) {
   1.379 +        pthread_cond_wait(&android_app->cond, &android_app->mutex);
   1.380 +    }
   1.381 +
   1.382 +    if (android_app->savedState != NULL) {
   1.383 +        savedState = android_app->savedState;
   1.384 +        *outLen = android_app->savedStateSize;
   1.385 +        android_app->savedState = NULL;
   1.386 +        android_app->savedStateSize = 0;
   1.387 +    }
   1.388 +
   1.389 +    pthread_mutex_unlock(&android_app->mutex);
   1.390 +
   1.391 +    return savedState;
   1.392 +}
   1.393 +
   1.394 +static void onPause(ANativeActivity* activity) {
   1.395 +    LOGV("Pause: %p\n", activity);
   1.396 +    android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE);
   1.397 +}
   1.398 +
   1.399 +static void onStop(ANativeActivity* activity) {
   1.400 +    LOGV("Stop: %p\n", activity);
   1.401 +    android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP);
   1.402 +}
   1.403 +
   1.404 +static void onConfigurationChanged(ANativeActivity* activity) {
   1.405 +    struct android_app* android_app = (struct android_app*)activity->instance;
   1.406 +    LOGV("ConfigurationChanged: %p\n", activity);
   1.407 +    android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
   1.408 +}
   1.409 +
   1.410 +static void onLowMemory(ANativeActivity* activity) {
   1.411 +    struct android_app* android_app = (struct android_app*)activity->instance;
   1.412 +    LOGV("LowMemory: %p\n", activity);
   1.413 +    android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY);
   1.414 +}
   1.415 +
   1.416 +static void onWindowFocusChanged(ANativeActivity* activity, int focused) {
   1.417 +    LOGV("WindowFocusChanged: %p -- %d\n", activity, focused);
   1.418 +    android_app_write_cmd((struct android_app*)activity->instance,
   1.419 +            focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
   1.420 +}
   1.421 +
   1.422 +static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) {
   1.423 +    LOGV("NativeWindowCreated: %p -- %p\n", activity, window);
   1.424 +    android_app_set_window((struct android_app*)activity->instance, window);
   1.425 +}
   1.426 +
   1.427 +static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) {
   1.428 +    LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window);
   1.429 +    android_app_set_window((struct android_app*)activity->instance, NULL);
   1.430 +}
   1.431 +
   1.432 +static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) {
   1.433 +    LOGV("InputQueueCreated: %p -- %p\n", activity, queue);
   1.434 +    android_app_set_input((struct android_app*)activity->instance, queue);
   1.435 +}
   1.436 +
   1.437 +static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) {
   1.438 +    LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue);
   1.439 +    android_app_set_input((struct android_app*)activity->instance, NULL);
   1.440 +}
   1.441 +
   1.442 +void ANativeActivity_onCreate(ANativeActivity* activity,
   1.443 +        void* savedState, size_t savedStateSize) {
   1.444 +    LOGV("Creating: %p\n", activity);
   1.445 +    activity->callbacks->onDestroy = onDestroy;
   1.446 +    activity->callbacks->onStart = onStart;
   1.447 +    activity->callbacks->onResume = onResume;
   1.448 +    activity->callbacks->onSaveInstanceState = onSaveInstanceState;
   1.449 +    activity->callbacks->onPause = onPause;
   1.450 +    activity->callbacks->onStop = onStop;
   1.451 +    activity->callbacks->onConfigurationChanged = onConfigurationChanged;
   1.452 +    activity->callbacks->onLowMemory = onLowMemory;
   1.453 +    activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
   1.454 +    activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
   1.455 +    activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
   1.456 +    activity->callbacks->onInputQueueCreated = onInputQueueCreated;
   1.457 +    activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
   1.458 +
   1.459 +    activity->instance = android_app_create(activity, savedState, savedStateSize);
   1.460 +}