Skip to content

Commit

Permalink
plugin: add app.datadir API to get writable path
Browse files Browse the repository at this point in the history
Adds app.datadir to the bridge to access a writable persistent path
from the nodejs-mobile runtime, which should be the FilesDir on
Android and the NSDocumentDirectory on iOS.
Also sets the os.tmpdir() to the CacheDir on Android.
  • Loading branch information
jaimecbernardo committed Mar 27, 2018
1 parent aac179b commit 2fec512
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,10 +103,24 @@ class EventChannel extends ChannelSuper {
* Emit pause/resume events when the app goes to background/foreground.
*/
class SystemChannel extends ChannelSuper {
constructor(name) {
super(name);
// datadir should not change during runtime, so we cache it.
this._cacheDataDir = null;
};

processData(data) {
// The data is the event.
this.emitWrapper(data);
};

// Get a writable data directory for persistent file storage.
datadir() {
if (this._cacheDataDir===null) {
this._cacheDataDir=NativeBridge.getDataDir();
}
return this._cacheDataDir;
};
};

/**
Expand Down
13 changes: 13 additions & 0 deletions src/android/java/com/janeasystems/cdvnodejsmobile/NodeJS.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.SharedPreferences;
import android.system.Os;
import android.system.ErrnoException;

import java.io.*;
import java.lang.System;
Expand Down Expand Up @@ -66,6 +68,7 @@ public class NodeJS extends CordovaPlugin {

public native Integer startNodeWithArguments(String[] arguments, String nodePath, boolean redirectOutputToLogcat);
public native void sendMessageToNodeChannel(String channelName, String msg);
public native void registerNodeDataDirPath(String dataDir);
public native String getCurrentABIName();

@Override
Expand All @@ -76,7 +79,17 @@ public void pluginInitialize() {
context = activity.getBaseContext();
assetManager = activity.getBaseContext().getAssets();

// Sets the TMPDIR environment to the cacheDir, to be used in Node as os.tmpdir
try {
Os.setenv("TMPDIR", context.getCacheDir().getAbsolutePath(),true);
} catch (ErrnoException e) {
e.printStackTrace();
}
filesDir = context.getFilesDir().getAbsolutePath();

// Register the filesDir as the Node data dir.
registerNodeDataDirPath(filesDir);

nodeAppRootAbsolutePath = filesDir + "/" + PROJECT_ROOT;
nodePath = nodeAppRootAbsolutePath + ":" + filesDir + "/" + BUILTIN_MODULES;
trashDir = filesDir + "/" + TRASH_DIR;
Expand Down
11 changes: 11 additions & 0 deletions src/android/jni/native-lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ Java_com_janeasystems_cdvnodejsmobile_NodeJS_sendMessageToNodeChannel(
env->ReleaseStringUTFChars(msg, nativeMessage);
}

extern "C"
JNIEXPORT void JNICALL
Java_com_janeasystems_cdvnodejsmobile_NodeJS_registerNodeDataDirPath(
JNIEnv *env,
jobject /* this */,
jstring dataDir) {
const char* nativeDataDir = env->GetStringUTFChars(dataDir, 0);
RegisterNodeDataDirPath(nativeDataDir);
env->ReleaseStringUTFChars(dataDir, nativeDataDir);
}

extern "C" int callintoNode(int argc, char *argv[]){
const int exit_code = node::Start(argc,argv);
return exit_code;
Expand Down
24 changes: 24 additions & 0 deletions src/common/cordova-bridge/cordova-bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,18 @@ void RegisterBridgeCallback(t_bridge_callback callback) {
cordova_callback = callback;
}

char* datadir_path = NULL;
/*
* Called by the Cordova plug-in to register the datadir,
* representing a writable path. Expected to be called once,
* while the plug-in initializes.
*/
void RegisterNodeDataDirPath(const char* path) {
size_t pathLength = strlen(path);
datadir_path = (char*)calloc(sizeof(char), pathLength + 1);
strncpy(datadir_path, path, pathLength);
}

/**
* Channel class
*/
Expand Down Expand Up @@ -309,13 +321,25 @@ napi_value Method_RegisterChannel(napi_env env, napi_callback_info info) {
return nullptr;
}

/**
* Get the registered datadir
*/
napi_value Method_GetDataDir(napi_env env, napi_callback_info info) {
NAPI_ASSERT(env, datadir_path!=NULL, "Data directory not set from native side.");
napi_value return_datadir;
size_t str_len = strlen(datadir_path);
NAPI_CALL(env, napi_create_string_utf8(env, datadir_path, str_len, &return_datadir));
return return_datadir;
}

#define DECLARE_NAPI_METHOD(name, func) { name, 0, func, 0, 0, 0, napi_default, 0 }

napi_value Init(napi_env env, napi_value exports) {
napi_status status;
napi_property_descriptor properties[] = {
DECLARE_NAPI_METHOD("sendMessage", Method_SendMessage),
DECLARE_NAPI_METHOD("registerChannel", Method_RegisterChannel),
DECLARE_NAPI_METHOD("getDataDir", Method_GetDataDir),
};
NAPI_CALL(env, napi_define_properties(env, exports, sizeof(properties) / sizeof(*properties), properties));
return exports;
Expand Down
1 change: 1 addition & 0 deletions src/common/cordova-bridge/cordova-bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@
typedef void (*t_bridge_callback)(const char* channelName, const char* message);
void RegisterBridgeCallback(t_bridge_callback);
void SendMessageToNodeChannel(const char* channelName, const char* message);
void RegisterNodeDataDirPath(const char* path);

#endif
4 changes: 4 additions & 0 deletions src/ios/CDVNodeJS.mm
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ - (void) pluginInitialize {

RegisterBridgeCallback(sendMessageToCordova);

// Register the Documents Directory as the node dataDir.
NSString* nodeDataDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
RegisterNodeDataDirPath([nodeDataDir UTF8String]);

NSString* nodePath = [[NSProcessInfo processInfo] environment][NODE_PATH];
NSString* appPath = [[NSBundle mainBundle] bundlePath];
NSString* builtinModulesPath = [appPath stringByAppendingString:BUILTIN_MODULES];
Expand Down

0 comments on commit 2fec512

Please sign in to comment.