Skip to content

Commit 2ceddb2

Browse files
refactor: Address review comments for Storage List API
Incorporates feedback from the initial review of the List API: - Build Fix: - Explicitly namespaced StorageReference in list_result.h to resolve undeclared identifier error. - Integration Tests: - Removed SKIP_TEST_ON_ANDROID_EMULATOR from ListAllBasic and ListPaginated tests. - Refactored list tests to create their own unique root folders instead of using a shared one in the test fixture, improving test isolation. - Code Style: - Removed unnecessary comments explaining header includes. - Removed placeholder comments from public headers. - Updated copyright year to 2025 in all newly added files. - Ran code formatter (scripts/format_code.py -git_diff) on all changed files. - Android Performance: - Optimized Android's ListResultInternal to cache converted items, prefixes, and page token. This avoids repeated JNI calls on subsequent accesses. - Cleanup Mechanism: - Simplified ListResult cleanup by removing the ListResultInternalCommon class. ListResult now directly manages the cleanup registration of its internal_ member, similar to StorageReference.
1 parent 989eb79 commit 2ceddb2

File tree

11 files changed

+167
-133
lines changed

11 files changed

+167
-133
lines changed

storage/integration_test/src/integration_test.cc

Lines changed: 91 additions & 70 deletions
Large diffs are not rendered by default.

storage/src/android/list_result_android.cc

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,7 @@ namespace internal {
3131
X(GetPageToken, "getPageToken", "()Ljava/lang/String;")
3232
// clang-format on
3333
METHOD_LOOKUP_DECLARATION(list_result, LIST_RESULT_METHODS)
34-
METHOD_LOOKUP_DEFINITION(list_result,
35-
"com/google/firebase/storage/ListResult",
34+
METHOD_LOOKUP_DEFINITION(list_result, "com/google/firebase/storage/ListResult",
3635
LIST_RESULT_METHODS)
3736

3837
// clang-format off
@@ -78,9 +77,9 @@ ListResultInternal::ListResultInternal(StorageInternal* storage_internal,
7877
ListResultInternal::ListResultInternal(const ListResultInternal& other)
7978
: storage_internal_(other.storage_internal_),
8079
list_result_java_ref_(nullptr),
81-
items_cache_(other.items_cache_), // Copy cache
82-
prefixes_cache_(other.prefixes_cache_), // Copy cache
83-
page_token_cache_(other.page_token_cache_), // Copy cache
80+
items_cache_(other.items_cache_), // Copy cache
81+
prefixes_cache_(other.prefixes_cache_), // Copy cache
82+
page_token_cache_(other.page_token_cache_), // Copy cache
8483
items_converted_(other.items_converted_),
8584
prefixes_converted_(other.prefixes_converted_),
8685
page_token_converted_(other.page_token_converted_) {
@@ -96,7 +95,8 @@ ListResultInternal& ListResultInternal::operator=(
9695
if (&other == this) {
9796
return *this;
9897
}
99-
storage_internal_ = other.storage_internal_; // This is a raw pointer, just copy.
98+
storage_internal_ =
99+
other.storage_internal_; // This is a raw pointer, just copy.
100100
FIREBASE_ASSERT(storage_internal_ != nullptr);
101101
JNIEnv* env = storage_internal_->app()->GetJNIEnv();
102102
if (list_result_java_ref_ != nullptr) {
@@ -132,24 +132,28 @@ std::vector<StorageReference> ListResultInternal::ProcessJavaReferenceList(
132132
}
133133

134134
JNIEnv* env = storage_internal_->app()->GetJNIEnv();
135-
jint size = env->CallIntMethod(java_list_ref, java_list::GetMethodId(java_list::kSize));
135+
jint size = env->CallIntMethod(java_list_ref,
136+
java_list::GetMethodId(java_list::kSize));
136137
if (env->ExceptionCheck()) {
137138
env->ExceptionClear();
138139
LogError("Failed to get size of Java List in ListResultInternal");
139140
return cpp_references;
140141
}
141142

142143
for (jint i = 0; i < size; ++i) {
143-
jobject java_storage_ref =
144-
env->CallObjectMethod(java_list_ref, java_list::GetMethodId(java_list::kGet), i);
144+
jobject java_storage_ref = env->CallObjectMethod(
145+
java_list_ref, java_list::GetMethodId(java_list::kGet), i);
145146
if (env->ExceptionCheck() || java_storage_ref == nullptr) {
146147
env->ExceptionClear();
147-
LogError("Failed to get StorageReference object from Java List at index %d", i);
148+
LogError(
149+
"Failed to get StorageReference object from Java List at index %d",
150+
i);
148151
if (java_storage_ref) env->DeleteLocalRef(java_storage_ref);
149152
continue;
150153
}
151154
// Create a C++ StorageReferenceInternal from the Java StorageReference.
152-
// StorageReferenceInternal constructor will create a global ref for the java obj.
155+
// StorageReferenceInternal constructor will create a global ref for the
156+
// java obj.
153157
StorageReferenceInternal* sfr_internal =
154158
new StorageReferenceInternal(storage_internal_, java_storage_ref);
155159
cpp_references.push_back(StorageReference(sfr_internal));
@@ -159,7 +163,7 @@ std::vector<StorageReference> ListResultInternal::ProcessJavaReferenceList(
159163
}
160164

161165
std::vector<StorageReference> ListResultInternal::items() const {
162-
if (!list_result_java_ref_) return items_cache_; // Return empty if no ref
166+
if (!list_result_java_ref_) return items_cache_; // Return empty if no ref
163167
if (items_converted_) {
164168
return items_cache_;
165169
}
@@ -191,7 +195,8 @@ std::vector<StorageReference> ListResultInternal::prefixes() const {
191195

192196
JNIEnv* env = storage_internal_->app()->GetJNIEnv();
193197
jobject java_prefixes_list = env->CallObjectMethod(
194-
list_result_java_ref_, list_result::GetMethodId(list_result::kGetPrefixes));
198+
list_result_java_ref_,
199+
list_result::GetMethodId(list_result::kGetPrefixes));
195200
if (env->ExceptionCheck() || java_prefixes_list == nullptr) {
196201
env->ExceptionClear();
197202
LogError("Failed to call getPrefixes() on Java ListResult");
@@ -214,20 +219,21 @@ std::string ListResultInternal::page_token() const {
214219

215220
JNIEnv* env = storage_internal_->app()->GetJNIEnv();
216221
jstring page_token_jstring = static_cast<jstring>(env->CallObjectMethod(
217-
list_result_java_ref_, list_result::GetMethodId(list_result::kGetPageToken)));
222+
list_result_java_ref_,
223+
list_result::GetMethodId(list_result::kGetPageToken)));
218224
if (env->ExceptionCheck()) {
219225
env->ExceptionClear();
220226
LogError("Failed to call getPageToken() on Java ListResult");
221227
if (page_token_jstring) env->DeleteLocalRef(page_token_jstring);
222228
page_token_converted_ = true;
223-
return page_token_cache_; // Return empty if error
229+
return page_token_cache_; // Return empty if error
224230
}
225231

226232
if (page_token_jstring != nullptr) {
227233
page_token_cache_ = util::JniStringToString(env, page_token_jstring);
228234
env->DeleteLocalRef(page_token_jstring);
229235
} else {
230-
page_token_cache_ = ""; // Explicitly set to empty if Java string is null
236+
page_token_cache_ = ""; // Explicitly set to empty if Java string is null
231237
}
232238

233239
page_token_converted_ = true;

storage/src/android/list_result_android.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
#include "firebase/app.h"
2525
#include "firebase/storage/storage_reference.h"
2626
#include "storage/src/common/storage_internal.h"
27-
// It's okay for platform specific internal headers to include common internal headers.
27+
// It's okay for platform specific internal headers to include common internal
28+
// headers.
2829
#include "storage/src/common/list_result_internal_common.h"
2930

30-
3131
namespace firebase {
3232
namespace storage {
3333

@@ -36,7 +36,8 @@ class ListResult;
3636

3737
namespace internal {
3838

39-
// Declare ListResultInternal a friend of ListResultInternalCommon for construction.
39+
// Declare ListResultInternal a friend of ListResultInternalCommon for
40+
// construction.
4041
class ListResultInternalCommon;
4142

4243
// Contains the Android-specific implementation of ListResultInternal.

storage/src/android/storage_reference_android.cc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ enum StorageReferenceFn {
111111
kStorageReferenceFnUpdateMetadata,
112112
kStorageReferenceFnPutBytes,
113113
kStorageReferenceFnPutFile,
114-
kStorageReferenceFnList, // New enum value for List operations
114+
kStorageReferenceFnList, // New enum value for List operations
115115
kStorageReferenceFnCount,
116116
};
117117

@@ -122,7 +122,7 @@ bool StorageReferenceInternal::Initialize(App* app) {
122122
return false;
123123
}
124124
if (!ListResultInternal::Initialize(app)) {
125-
storage_reference::ReleaseClass(env); // Release what was cached
125+
storage_reference::ReleaseClass(env); // Release what was cached
126126
return false;
127127
}
128128
return true;
@@ -331,7 +331,7 @@ void StorageReferenceInternal::FutureCallback(JNIEnv* env, jobject result,
331331
jobject result_ref = env->NewLocalRef(result);
332332
ListResultInternal* list_result_internal_ptr =
333333
new ListResultInternal(data->storage, result_ref);
334-
env->DeleteLocalRef(result_ref); // ListResultInternal made a global ref.
334+
env->DeleteLocalRef(result_ref); // ListResultInternal made a global ref.
335335

336336
data->impl->Complete<ListResult>(
337337
data->handle, kErrorNone, status_message,
@@ -345,11 +345,15 @@ void StorageReferenceInternal::FutureCallback(JNIEnv* env, jobject result,
345345
// This case might need adjustment if List operations that fail end up here
346346
// without a specific exception being caught by result_code check.
347347
if (data->func == kStorageReferenceFnList) {
348-
// If it was a list operation but didn't result in a ListResult object (e.g. error not caught as exception)
349-
// complete with an error and an invalid ListResult.
350-
data->impl->CompleteWithResult(data->handle, kErrorUnknown, "List operation failed to produce a valid ListResult.", ListResult(nullptr));
348+
// If it was a list operation but didn't result in a ListResult object
349+
// (e.g. error not caught as exception) complete with an error and an
350+
// invalid ListResult.
351+
data->impl->CompleteWithResult(
352+
data->handle, kErrorUnknown,
353+
"List operation failed to produce a valid ListResult.",
354+
ListResult(nullptr));
351355
} else {
352-
data->impl->Complete(data->handle, kErrorNone, status_message);
356+
data->impl->Complete(data->handle, kErrorNone, status_message);
353357
}
354358
}
355359
if (data->listener != nullptr) {

storage/src/common/list_result.cc

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,11 @@
1717
#include <assert.h>
1818

1919
// #include "storage/src/common/list_result_internal_common.h" // Removed
20-
#include "storage/src/common/storage_internal.h" // Required for StorageInternal, CleanupNotifier
21-
#include "storage/src/common/storage_reference_internal.h" // For StorageReference constructor from internal
22-
#include "app/src/include/firebase/app.h" // For App, LogDebug
23-
#include "app/src/util.h" // For LogDebug
24-
#include "app/src/cleanup_notifier.h" // For CleanupNotifier
25-
20+
#include "app/src/cleanup_notifier.h" // For CleanupNotifier
21+
#include "app/src/include/firebase/app.h" // For App, LogDebug
22+
#include "app/src/util.h" // For LogDebug
23+
#include "storage/src/common/storage_internal.h" // Required for StorageInternal, CleanupNotifier
24+
#include "storage/src/common/storage_reference_internal.h" // For StorageReference constructor from internal
2625

2726
// Platform specific ListResultInternal definitions
2827
#if FIREBASE_PLATFORM_ANDROID
@@ -31,7 +30,8 @@
3130
#include "storage/src/ios/list_result_ios.h"
3231
#elif FIREBASE_PLATFORM_DESKTOP
3332
#include "storage/src/desktop/list_result_desktop.h"
34-
#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS, FIREBASE_PLATFORM_DESKTOP
33+
#endif // FIREBASE_PLATFORM_ANDROID, FIREBASE_PLATFORM_IOS,
34+
// FIREBASE_PLATFORM_DESKTOP
3535

3636
namespace firebase {
3737
namespace storage {
@@ -40,8 +40,8 @@ using internal::ListResultInternal;
4040
// using internal::ListResultInternalCommon; // Removed
4141

4242
// Global function to be called by CleanupNotifier
43-
// This function is responsible for cleaning up the internal state of a ListResult
44-
// object when the App is being shut down.
43+
// This function is responsible for cleaning up the internal state of a
44+
// ListResult object when the App is being shut down.
4545
static void GlobalCleanupListResult(void* list_result_void) {
4646
if (list_result_void) {
4747
ListResult* list_result = static_cast<ListResult*>(list_result_void);
@@ -167,8 +167,9 @@ ListResult::~ListResult() {
167167

168168
void ListResult::ClearInternalForCleanup() {
169169
// This method is called by GlobalCleanupListResult.
170-
// The object is already unregistered from the CleanupNotifier by the notifier itself
171-
// before this callback is invoked. So, no need to call UnregisterObject here.
170+
// The object is already unregistered from the CleanupNotifier by the notifier
171+
// itself before this callback is invoked. So, no need to call
172+
// UnregisterObject here.
172173
delete internal_;
173174
internal_ = nullptr;
174175
}

storage/src/common/storage_reference.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
#include "storage/src/include/firebase/storage/storage_reference.h"
1616

1717
#include "app/src/assert.h"
18-
#include "firebase/storage/list_result.h" // Required for ListResult
19-
#include "storage/src/include/firebase/storage/future_details.h" // Required for Future<ListResult>
18+
#include "firebase/storage/list_result.h" // Required for ListResult
19+
#include "storage/src/include/firebase/storage/future_details.h" // Required for Future<ListResult>
2020

2121
#ifdef __APPLE__
2222
#include "TargetConditionals.h"

storage/src/desktop/list_result_desktop.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
// limitations under the License.
1414

1515
#include "storage/src/desktop/list_result_desktop.h"
16-
#include "storage/src/desktop/storage_desktop.h" // For StorageInternal
16+
17+
#include "storage/src/desktop/storage_desktop.h" // For StorageInternal
1718

1819
namespace firebase {
1920
namespace storage {
@@ -28,10 +29,9 @@ ListResultInternal::ListResultInternal(
2829
const std::vector<StorageReference>& prefixes,
2930
const std::string& page_token)
3031
: storage_internal_(storage_internal),
31-
items_stub_(items), // Will be empty for stubs
32-
prefixes_stub_(prefixes), // Will be empty for stubs
33-
page_token_stub_(page_token) {} // Will be empty for stubs
34-
32+
items_stub_(items), // Will be empty for stubs
33+
prefixes_stub_(prefixes), // Will be empty for stubs
34+
page_token_stub_(page_token) {} // Will be empty for stubs
3535

3636
ListResultInternal::ListResultInternal(const ListResultInternal& other)
3737
: storage_internal_(other.storage_internal_),
@@ -44,7 +44,7 @@ ListResultInternal& ListResultInternal::operator=(
4444
if (&other == this) {
4545
return *this;
4646
}
47-
storage_internal_ = other.storage_internal_; // Pointer copy
47+
storage_internal_ = other.storage_internal_; // Pointer copy
4848
items_stub_ = other.items_stub_;
4949
prefixes_stub_ = other.prefixes_stub_;
5050
page_token_stub_ = other.page_token_stub_;

storage/src/desktop/list_result_desktop.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@
2020

2121
#include "firebase/storage/storage_reference.h"
2222
#include "storage/src/common/storage_internal.h"
23-
// It's okay for platform specific internal headers to include common internal headers.
23+
// It's okay for platform specific internal headers to include common internal
24+
// headers.
2425
#include "storage/src/common/list_result_internal_common.h"
2526

26-
2727
namespace firebase {
2828
namespace storage {
2929

@@ -32,7 +32,8 @@ class ListResult;
3232

3333
namespace internal {
3434

35-
// Declare ListResultInternal a friend of ListResultInternalCommon for construction.
35+
// Declare ListResultInternal a friend of ListResultInternalCommon for
36+
// construction.
3637
class ListResultInternalCommon;
3738

3839
// Contains the Desktop-specific implementation of ListResultInternal (stubs).
@@ -47,7 +48,6 @@ class ListResultInternal {
4748
const std::vector<StorageReference>& prefixes,
4849
const std::string& page_token);
4950

50-
5151
// Destructor (default is fine).
5252
~ListResultInternal() = default;
5353

@@ -57,7 +57,6 @@ class ListResultInternal {
5757
// Copy assignment operator.
5858
ListResultInternal& operator=(const ListResultInternal& other);
5959

60-
6160
// Gets the items (files) in this result (stub).
6261
std::vector<StorageReference> items() const {
6362
return std::vector<StorageReference>();
@@ -80,7 +79,7 @@ class ListResultInternal {
8079
// storage_internal().
8180
friend class ListResultInternalCommon;
8281

83-
StorageInternal* storage_internal_; // Not owned.
82+
StorageInternal* storage_internal_; // Not owned.
8483
// Desktop stubs don't actually store these, but defined to match constructor.
8584
std::vector<StorageReference> items_stub_;
8685
std::vector<StorageReference> prefixes_stub_;

storage/src/desktop/storage_reference_desktop.cc

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@
2828
#include "app/src/function_registry.h"
2929
#include "app/src/include/firebase/app.h"
3030
#include "app/src/thread.h"
31+
#include "firebase/storage/list_result.h" // Added for ListResult
3132
#include "storage/src/common/common_internal.h"
3233
#include "storage/src/desktop/controller_desktop.h"
34+
#include "storage/src/desktop/list_result_desktop.h" // Added for ListResultInternal
3335
#include "storage/src/desktop/metadata_desktop.h"
3436
#include "storage/src/desktop/storage_desktop.h"
3537
#include "storage/src/include/firebase/storage.h"
3638
#include "storage/src/include/firebase/storage/common.h"
37-
#include "firebase/storage/list_result.h" // Added for ListResult
38-
#include "storage/src/desktop/list_result_desktop.h" // Added for ListResultInternal
3939

4040
namespace firebase {
4141
namespace storage {
@@ -704,9 +704,9 @@ Future<ListResult> StorageReferenceInternal::List(int32_t max_results) {
704704
ReferenceCountedFutureImpl* future_api = future();
705705
SafeFutureHandle<ListResult> handle =
706706
future_api->SafeAlloc<ListResult>(kStorageReferenceFnList);
707-
future_api->CompleteWithResult(
708-
handle, kErrorUnimplemented,
709-
"List operation is not supported on desktop.", ListResult(nullptr));
707+
future_api->CompleteWithResult(handle, kErrorUnimplemented,
708+
"List operation is not supported on desktop.",
709+
ListResult(nullptr));
710710
return ListLastResult();
711711
}
712712

@@ -715,9 +715,9 @@ Future<ListResult> StorageReferenceInternal::List(int32_t max_results,
715715
ReferenceCountedFutureImpl* future_api = future();
716716
SafeFutureHandle<ListResult> handle =
717717
future_api->SafeAlloc<ListResult>(kStorageReferenceFnList);
718-
future_api->CompleteWithResult(
719-
handle, kErrorUnimplemented,
720-
"List operation is not supported on desktop.", ListResult(nullptr));
718+
future_api->CompleteWithResult(handle, kErrorUnimplemented,
719+
"List operation is not supported on desktop.",
720+
ListResult(nullptr));
721721
return ListLastResult();
722722
}
723723

storage/src/desktop/storage_reference_desktop.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,11 +146,13 @@ class StorageReferenceInternal {
146146
// Returns the result of the most recent call to Write();
147147
Future<Metadata> PutFileLastResult();
148148

149-
// Asynchronously lists objects and common prefixes under this reference (stub).
149+
// Asynchronously lists objects and common prefixes under this reference
150+
// (stub).
150151
Future<ListResult> List(int32_t max_results);
151152
Future<ListResult> List(int32_t max_results, const char* page_token);
152153

153-
// Asynchronously lists all objects and common prefixes under this reference (stub).
154+
// Asynchronously lists all objects and common prefixes under this reference
155+
// (stub).
154156
Future<ListResult> ListAll();
155157

156158
// Returns the result of the most recent List operation (stub).

storage/src/include/firebase/storage/list_result.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,10 @@ class ListResult {
5858
~ListResult();
5959

6060
/// @brief Returns the items (files) in this result.
61-
std::vector<StorageReference> items() const;
61+
std::vector<firebase::storage::StorageReference> items() const;
6262

6363
/// @brief Returns the prefixes (folders) in this result.
64-
std::vector<StorageReference> prefixes() const;
64+
std::vector<firebase::storage::StorageReference> prefixes() const;
6565

6666
/// @brief If set, there are more results to retrieve.
6767
///

0 commit comments

Comments
 (0)