Skip to content

Commit fa48ba4

Browse files
fix: align endpoints with latest rv
1 parent 8b1b6d6 commit fa48ba4

11 files changed

Lines changed: 183 additions & 8 deletions

File tree

ViroRenderer/VROARSession.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ class VROARSession {
585585
}
586586

587587
/*
588-
Update an existing geospatial anchor (link scene asset, scene, or rename).
588+
Update an existing geospatial anchor (link scene asset, scene, user asset, or rename).
589589
Pass empty strings to leave a field unchanged.
590590
Callback receives (success, jsonData, error).
591591
*/
@@ -594,10 +594,26 @@ class VROARSession {
594594
const std::string& sceneAssetId,
595595
const std::string& sceneId,
596596
const std::string& name,
597+
const std::string& userAssetId,
597598
std::function<void(bool success, std::string jsonData, std::string error)> callback) {
598599
if (callback) callback(false, "", "Not supported");
599600
}
600601

602+
/*
603+
Upload a file to ReactVision storage and return a user_asset_id.
604+
filePath must be a local file path readable by the native layer.
605+
assetType: "3d-model" | "image" | "video" | "audio"
606+
Callback receives (success, userAssetId, fileUrl, error).
607+
*/
608+
virtual void rvUploadAsset(
609+
const std::string& filePath,
610+
const std::string& assetType,
611+
const std::string& fileName,
612+
const std::string& appUserId,
613+
std::function<void(bool success, std::string userAssetId, std::string fileUrl, std::string error)> callback) {
614+
if (callback) callback(false, "", "", "Not supported");
615+
}
616+
601617
/*
602618
Permanently delete a geospatial anchor from the ReactVision backend.
603619
Callback receives (success, error).

android/sharedCode/src/main/cpp/arcore/ARSceneController_JNI.cpp

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -537,29 +537,82 @@ VRO_METHOD(void, nativeRvUpdateGeospatialAnchor)(VRO_ARGS
537537
jstring anchorId_j,
538538
jstring sceneAssetId_j,
539539
jstring sceneId_j,
540-
jstring name_j) {
540+
jstring name_j,
541+
jstring userAssetId_j) {
541542
std::string keyStr = VRO_STRING_STL(key_j);
542543
std::string anchorStr = VRO_STRING_STL(anchorId_j);
543544
std::string sceneAssetStr = VRO_STRING_STL(sceneAssetId_j);
544545
std::string sceneIdStr = VRO_STRING_STL(sceneId_j);
545546
std::string nameStr = VRO_STRING_STL(name_j);
547+
std::string userAssetStr = VRO_STRING_STL(userAssetId_j);
546548
std::weak_ptr<VROARScene> arScene_w = std::dynamic_pointer_cast<VROARScene>(
547549
VRO_REF_GET(VROARSceneController, arSceneControllerPtr)->getScene());
548550
VRO_WEAK weakObj = VRO_NEW_WEAK_GLOBAL_REF(obj);
549-
VROPlatformDispatchAsyncRenderer([arScene_w, weakObj, keyStr, anchorStr, sceneAssetStr, sceneIdStr, nameStr] {
551+
VROPlatformDispatchAsyncRenderer([arScene_w, weakObj, keyStr, anchorStr, sceneAssetStr, sceneIdStr, nameStr, userAssetStr] {
550552
std::shared_ptr<VROARScene> arScene = arScene_w.lock();
551553
std::shared_ptr<VROARSession> arSession = arScene ? arScene->getARSession() : nullptr;
552554
if (!arSession) {
553555
rvFireGeoResult(weakObj, keyStr, false, "", "AR session not available");
554556
return;
555557
}
556-
arSession->rvUpdateGeospatialAnchor(anchorStr, sceneAssetStr, sceneIdStr, nameStr,
558+
arSession->rvUpdateGeospatialAnchor(anchorStr, sceneAssetStr, sceneIdStr, nameStr, userAssetStr,
557559
[weakObj, keyStr](bool success, std::string jsonData, std::string error) {
558560
rvFireGeoResult(weakObj, keyStr, success, jsonData, error);
559561
});
560562
});
561563
}
562564

565+
static void rvFireUploadResult(VRO_WEAK weakObj, std::string keyStr,
566+
bool success, std::string assetId, std::string fileUrl, std::string error) {
567+
VROPlatformDispatchAsyncApplication([weakObj, keyStr, success, assetId, fileUrl, error] {
568+
VRO_ENV env = VROPlatformGetJNIEnv();
569+
VRO_OBJECT localObj = VRO_NEW_LOCAL_REF(weakObj);
570+
if (VRO_IS_OBJECT_NULL(localObj)) {
571+
VRO_DELETE_LOCAL_REF(localObj);
572+
VRO_DELETE_WEAK_GLOBAL_REF(weakObj);
573+
return;
574+
}
575+
VRO_STRING jKey = VRO_NEW_STRING(keyStr.c_str());
576+
VRO_STRING jAssetId = VRO_NEW_STRING(assetId.c_str());
577+
VRO_STRING jFileUrl = VRO_NEW_STRING(fileUrl.c_str());
578+
VRO_STRING jErr = VRO_NEW_STRING(error.c_str());
579+
VROPlatformCallHostFunction(localObj, "onRvUploadResult",
580+
"(Ljava/lang/String;ZLjava/lang/String;Ljava/lang/String;Ljava/lang/String;)V",
581+
jKey, (jboolean)success, jAssetId, jFileUrl, jErr);
582+
VRO_DELETE_LOCAL_REF(localObj);
583+
VRO_DELETE_WEAK_GLOBAL_REF(weakObj);
584+
});
585+
}
586+
587+
VRO_METHOD(void, nativeRvUploadAsset)(VRO_ARGS
588+
VRO_REF(VROARSceneController) arSceneControllerPtr,
589+
jstring key_j,
590+
jstring filePath_j,
591+
jstring assetType_j,
592+
jstring fileName_j,
593+
jstring appUserId_j) {
594+
std::string keyStr = VRO_STRING_STL(key_j);
595+
std::string filePathStr = VRO_STRING_STL(filePath_j);
596+
std::string assetTypeStr = VRO_STRING_STL(assetType_j);
597+
std::string fileNameStr = VRO_STRING_STL(fileName_j);
598+
std::string appUserStr = VRO_STRING_STL(appUserId_j);
599+
std::weak_ptr<VROARScene> arScene_w = std::dynamic_pointer_cast<VROARScene>(
600+
VRO_REF_GET(VROARSceneController, arSceneControllerPtr)->getScene());
601+
VRO_WEAK weakObj = VRO_NEW_WEAK_GLOBAL_REF(obj);
602+
VROPlatformDispatchAsyncRenderer([arScene_w, weakObj, keyStr, filePathStr, assetTypeStr, fileNameStr, appUserStr] {
603+
std::shared_ptr<VROARScene> arScene = arScene_w.lock();
604+
std::shared_ptr<VROARSession> arSession = arScene ? arScene->getARSession() : nullptr;
605+
if (!arSession) {
606+
rvFireUploadResult(weakObj, keyStr, false, "", "", "AR session not available");
607+
return;
608+
}
609+
arSession->rvUploadAsset(filePathStr, assetTypeStr, fileNameStr, appUserStr,
610+
[weakObj, keyStr](bool success, std::string assetId, std::string fileUrl, std::string error) {
611+
rvFireUploadResult(weakObj, keyStr, success, assetId, fileUrl, error);
612+
});
613+
});
614+
}
615+
563616
VRO_METHOD(void, nativeRvDeleteGeospatialAnchor)(VRO_ARGS
564617
VRO_REF(VROARSceneController) arSceneControllerPtr,
565618
jstring key_j,

android/sharedCode/src/main/cpp/arcore/VROARSessionARCore.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "VROCameraTexture.h"
3636
#include "VROCloudAnchorProviderARCore.h"
3737
#include "VROCloudAnchorProviderReactVision.h"
38+
#include <fstream>
3839

3940
#ifndef RVCCA_AVAILABLE
4041
# define RVCCA_AVAILABLE 0
@@ -1978,13 +1979,15 @@ void VROARSessionARCore::rvUpdateGeospatialAnchor(
19781979
const std::string& sceneAssetId,
19791980
const std::string& sceneId,
19801981
const std::string& name,
1982+
const std::string& userAssetId,
19811983
std::function<void(bool, std::string, std::string)> callback) {
19821984
#if RVCCA_AVAILABLE
19831985
if (_geospatialProviderRV) {
19841986
ReactVisionCCA::GeospatialUpdateRequest req;
19851987
if (!sceneAssetId.empty()) req.sceneAssetId = sceneAssetId;
19861988
if (!sceneId.empty()) req.sceneId = sceneId;
19871989
if (!name.empty()) req.name = name;
1990+
if (!userAssetId.empty()) req.userAssetId = userAssetId;
19881991
_geospatialProviderRV->updateAnchor(anchorId, req,
19891992
[callback](ReactVisionCCA::ApiResult<ReactVisionCCA::GeospatialAnchorRecord> r) {
19901993
if (callback) {
@@ -1998,6 +2001,37 @@ void VROARSessionARCore::rvUpdateGeospatialAnchor(
19982001
if (callback) callback(false, "", "ReactVision geospatial provider not available");
19992002
}
20002003

2004+
void VROARSessionARCore::rvUploadAsset(
2005+
const std::string& filePath,
2006+
const std::string& assetType,
2007+
const std::string& fileName,
2008+
const std::string& appUserId,
2009+
std::function<void(bool, std::string, std::string, std::string)> callback) {
2010+
#if RVCCA_AVAILABLE
2011+
if (_geospatialProviderRV) {
2012+
// Strip "file://" prefix — std::ifstream needs a plain filesystem path
2013+
std::string path = filePath;
2014+
if (path.rfind("file://", 0) == 0) path = path.substr(7);
2015+
std::ifstream file(path, std::ios::binary);
2016+
if (!file.is_open()) {
2017+
if (callback) callback(false, "", "", "Failed to open file: " + path);
2018+
return;
2019+
}
2020+
std::vector<uint8_t> bytes((std::istreambuf_iterator<char>(file)), {});
2021+
file.close();
2022+
_geospatialProviderRV->uploadAsset(assetType, fileName, bytes, appUserId,
2023+
[callback](ReactVisionCCA::ApiResult<ReactVisionCCA::AssetUploadResult> r) {
2024+
if (callback) {
2025+
if (r.success) callback(true, r.data.id, r.data.url.empty() ? r.data.fileUrl : r.data.url, "");
2026+
else callback(false, "", "", r.error.message);
2027+
}
2028+
});
2029+
return;
2030+
}
2031+
#endif
2032+
if (callback) callback(false, "", "", "ReactVision geospatial provider not available");
2033+
}
2034+
20012035
void VROARSessionARCore::rvDeleteGeospatialAnchor(
20022036
const std::string& anchorId,
20032037
std::function<void(bool, std::string)> callback) {

android/sharedCode/src/main/cpp/arcore/VROARSessionARCore.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,11 @@ class VROARSessionARCore : public VROARSession,
192192
std::function<void(bool, std::string, std::string)> callback) override;
193193
void rvUpdateGeospatialAnchor(const std::string& anchorId,
194194
const std::string& sceneAssetId, const std::string& sceneId, const std::string& name,
195+
const std::string& userAssetId,
195196
std::function<void(bool, std::string, std::string)> callback) override;
197+
void rvUploadAsset(const std::string& filePath, const std::string& assetType,
198+
const std::string& fileName, const std::string& appUserId,
199+
std::function<void(bool, std::string, std::string, std::string)> callback) override;
196200
void rvDeleteGeospatialAnchor(const std::string& anchorId,
197201
std::function<void(bool, std::string)> callback) override;
198202
void rvListGeospatialAnchors(int limit, int offset,

android/sharedCode/src/main/java/com/viro/core/ARScene.java

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,6 +1130,7 @@ public void getCameraGeospatialPose(GeospatialPoseListener listener) {
11301130
public void setLastKnownLocation(double lat, double lng, double alt,
11311131
double horizAcc, double vertAcc,
11321132
double heading, double headingAcc) {
1133+
if (mNativeRef == 0) return;
11331134
nativeSetLastKnownLocation(mNativeRef, lat, lng, alt,
11341135
horizAcc, vertAcc, heading, headingAcc);
11351136
}
@@ -1259,15 +1260,41 @@ public void rvFindNearbyGeospatialAnchors(double lat, double lng, double radius,
12591260
nativeRvFindNearbyGeospatialAnchors(mNativeRef, key, lat, lng, radius, limit);
12601261
}
12611262

1262-
/** ReactVision — update an anchor (link scene asset / scene / rename). */
1263+
/** ReactVision — update an anchor (link scene asset / scene / rename / user asset). */
12631264
public void rvUpdateGeospatialAnchor(String anchorId, String sceneAssetId, String sceneId,
1264-
String name, RvGeospatialCallback callback) {
1265+
String name, String userAssetId,
1266+
RvGeospatialCallback callback) {
12651267
String key = "rvUpdate_" + System.nanoTime();
12661268
mRvGeospatialCallbacks.put(key, callback);
12671269
nativeRvUpdateGeospatialAnchor(mNativeRef, key, anchorId,
12681270
sceneAssetId != null ? sceneAssetId : "",
12691271
sceneId != null ? sceneId : "",
1270-
name != null ? name : "");
1272+
name != null ? name : "",
1273+
userAssetId != null ? userAssetId : "");
1274+
}
1275+
1276+
/** Callback for ReactVision asset upload operations. */
1277+
public interface RvUploadAssetCallback {
1278+
void onResult(boolean success, String userAssetId, String fileUrl, String error);
1279+
}
1280+
1281+
private Map<String, RvUploadAssetCallback> mRvUploadCallbacks = new HashMap<>();
1282+
1283+
void onRvUploadResult(String key, boolean success, String userAssetId, String fileUrl, String error) {
1284+
RvUploadAssetCallback cb = mRvUploadCallbacks.remove(key);
1285+
if (cb != null) cb.onResult(success, userAssetId, fileUrl, error);
1286+
}
1287+
1288+
/** ReactVision — upload an asset file and return its user_asset_id. */
1289+
public void rvUploadAsset(String filePath, String assetType, String fileName,
1290+
String appUserId, RvUploadAssetCallback callback) {
1291+
String key = "rvUpload_" + System.nanoTime();
1292+
mRvUploadCallbacks.put(key, callback);
1293+
nativeRvUploadAsset(mNativeRef, key,
1294+
filePath != null ? filePath : "",
1295+
assetType != null ? assetType : "",
1296+
fileName != null ? fileName : "",
1297+
appUserId != null ? appUserId : "");
12711298
}
12721299

12731300
/** ReactVision — delete an anchor permanently. */
@@ -1642,7 +1669,11 @@ private native void nativeRvFindNearbyGeospatialAnchors(long sceneControllerRef,
16421669
double radius, int limit);
16431670
private native void nativeRvUpdateGeospatialAnchor(long sceneControllerRef, String key,
16441671
String anchorId, String sceneAssetId,
1645-
String sceneId, String name);
1672+
String sceneId, String name,
1673+
String userAssetId);
1674+
private native void nativeRvUploadAsset(long sceneControllerRef, String key,
1675+
String filePath, String assetType,
1676+
String fileName, String appUserId);
16461677
private native void nativeRvDeleteGeospatialAnchor(long sceneControllerRef, String key,
16471678
String anchorId);
16481679
private native void nativeRvListGeospatialAnchors(long sceneControllerRef, String key,
Binary file not shown.
Binary file not shown.
5.96 KB
Binary file not shown.
11.8 KB
Binary file not shown.

ios/ViroKit/VROARSessioniOS.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2037,13 +2037,15 @@ void VROARSessioniOS::rvUpdateGeospatialAnchor(
20372037
const std::string& sceneAssetId,
20382038
const std::string& sceneId,
20392039
const std::string& name,
2040+
const std::string& userAssetId,
20402041
std::function<void(bool, std::string, std::string)> callback) {
20412042
#if RVCCA_AVAILABLE
20422043
if (_geospatialProviderRV) {
20432044
ReactVisionCCA::GeospatialUpdateRequest req;
20442045
if (!sceneAssetId.empty()) req.sceneAssetId = sceneAssetId;
20452046
if (!sceneId.empty()) req.sceneId = sceneId;
20462047
if (!name.empty()) req.name = name;
2048+
if (!userAssetId.empty()) req.userAssetId = userAssetId;
20472049
_geospatialProviderRV->updateAnchor(anchorId, req,
20482050
[callback](ReactVisionCCA::ApiResult<ReactVisionCCA::GeospatialAnchorRecord> r) {
20492051
if (callback) {
@@ -2057,6 +2059,37 @@ void VROARSessioniOS::rvUpdateGeospatialAnchor(
20572059
if (callback) callback(false, "", "ReactVision geospatial provider not available");
20582060
}
20592061

2062+
void VROARSessioniOS::rvUploadAsset(
2063+
const std::string& filePath,
2064+
const std::string& assetType,
2065+
const std::string& fileName,
2066+
const std::string& appUserId,
2067+
std::function<void(bool, std::string, std::string, std::string)> callback) {
2068+
#if RVCCA_AVAILABLE
2069+
if (_geospatialProviderRV) {
2070+
// Read file bytes from local URI/path
2071+
NSURL *url = [NSURL URLWithString:[NSString stringWithUTF8String:filePath.c_str()]];
2072+
if (!url) url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:filePath.c_str()]];
2073+
NSData *nsData = [NSData dataWithContentsOfURL:url];
2074+
if (!nsData) {
2075+
if (callback) callback(false, "", "", "Failed to read file at path: " + filePath);
2076+
return;
2077+
}
2078+
std::vector<uint8_t> bytes((const uint8_t*)nsData.bytes,
2079+
(const uint8_t*)nsData.bytes + nsData.length);
2080+
_geospatialProviderRV->uploadAsset(assetType, fileName, bytes, appUserId,
2081+
[callback](ReactVisionCCA::ApiResult<ReactVisionCCA::AssetUploadResult> r) {
2082+
if (callback) {
2083+
if (r.success) callback(true, r.data.id, r.data.url.empty() ? r.data.fileUrl : r.data.url, "");
2084+
else callback(false, "", "", r.error.message);
2085+
}
2086+
});
2087+
return;
2088+
}
2089+
#endif
2090+
if (callback) callback(false, "", "", "ReactVision geospatial provider not available");
2091+
}
2092+
20602093
void VROARSessioniOS::rvDeleteGeospatialAnchor(
20612094
const std::string& anchorId,
20622095
std::function<void(bool, std::string)> callback) {

0 commit comments

Comments
 (0)