diff --git a/packages/firebase_storage/firebase_storage/android/build.gradle b/packages/firebase_storage/firebase_storage/android/build.gradle index cbd0de9d4ba6..7ef42fddf333 100755 --- a/packages/firebase_storage/firebase_storage/android/build.gradle +++ b/packages/firebase_storage/firebase_storage/android/build.gradle @@ -5,10 +5,15 @@ apply plugin: 'com.android.library' apply from: file("local-config.gradle") buildscript { + ext.kotlin_version = "1.8.22" repositories { google() mavenCentral() } + dependencies { + classpath 'com.android.tools.build:gradle:8.1.4' + classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") + } } rootProject.allprojects { @@ -39,6 +44,8 @@ def getRootProjectExtOrCoreProperty(name, firebaseCoreProject) { return rootProject.ext.get('FlutterFire').get(name) } +apply plugin: 'kotlin-android' + android { // Conditional for compatibility with AGP <4.2. if (project.android.hasProperty("namespace")) { @@ -52,11 +59,20 @@ android { testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + kotlinOptions { + jvmTarget = project.ext.javaVersion + } + compileOptions { sourceCompatibility project.ext.javaVersion targetCompatibility project.ext.javaVersion } + sourceSets { + main.java.srcDirs += "src/main/kotlin" + test.java.srcDirs += "src/test/kotlin" + } + buildFeatures { buildConfig = true } diff --git a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseAppRegistrar.java b/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseAppRegistrar.java deleted file mode 100644 index 6c9664d0d36d..000000000000 --- a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseAppRegistrar.java +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package io.flutter.plugins.firebase.storage; - -import androidx.annotation.Keep; -import com.google.firebase.components.Component; -import com.google.firebase.components.ComponentRegistrar; -import com.google.firebase.platforminfo.LibraryVersionComponent; -import java.util.Collections; -import java.util.List; - -@Keep -public class FlutterFirebaseAppRegistrar implements ComponentRegistrar { - @Override - public List> getComponents() { - return Collections.>singletonList( - LibraryVersionComponent.create(BuildConfig.LIBRARY_NAME, BuildConfig.LIBRARY_VERSION)); - } -} diff --git a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageException.java b/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageException.java deleted file mode 100644 index 184d9a38b636..000000000000 --- a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageException.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2022, the Chromium project authors. Please see the AUTHORS file - * for details. All rights reserved. Use of this source code is governed by a - * BSD-style license that can be found in the LICENSE file. - */ - -package io.flutter.plugins.firebase.storage; - -import androidx.annotation.Nullable; -import com.google.firebase.storage.StorageException; - -class FlutterFirebaseStorageException { - static GeneratedAndroidFirebaseStorage.FlutterError parserExceptionToFlutter( - @Nullable Exception nativeException) { - if (nativeException == null) { - return new GeneratedAndroidFirebaseStorage.FlutterError( - "UNKNOWN", "An unknown error occurred", null); - } - String code = "UNKNOWN"; - String message = "An unknown error occurred:" + nativeException.getMessage(); - int codeNumber; - - if (nativeException instanceof StorageException) { - codeNumber = ((StorageException) nativeException).getErrorCode(); - code = getCode(codeNumber); - message = getMessage(codeNumber); - } - - return new GeneratedAndroidFirebaseStorage.FlutterError(code, message, null); - } - - public static String getCode(int codeNumber) { - switch (codeNumber) { - case StorageException.ERROR_OBJECT_NOT_FOUND: - return "object-not-found"; - case StorageException.ERROR_BUCKET_NOT_FOUND: - return "bucket-not-found"; - case StorageException.ERROR_PROJECT_NOT_FOUND: - return "project-not-found"; - case StorageException.ERROR_QUOTA_EXCEEDED: - return "quota-exceeded"; - case StorageException.ERROR_NOT_AUTHENTICATED: - return "unauthenticated"; - case StorageException.ERROR_NOT_AUTHORIZED: - return "unauthorized"; - case StorageException.ERROR_RETRY_LIMIT_EXCEEDED: - return "retry-limit-exceeded"; - case StorageException.ERROR_INVALID_CHECKSUM: - return "invalid-checksum"; - case StorageException.ERROR_CANCELED: - return "canceled"; - case StorageException.ERROR_UNKNOWN: - default: - { - return "unknown"; - } - } - } - - public static String getMessage(int codeNumber) { - switch (codeNumber) { - case StorageException.ERROR_OBJECT_NOT_FOUND: - return "No object exists at the desired reference."; - case StorageException.ERROR_BUCKET_NOT_FOUND: - return "No bucket is configured for Firebase Storage."; - case StorageException.ERROR_PROJECT_NOT_FOUND: - return "No project is configured for Firebase Storage."; - case StorageException.ERROR_QUOTA_EXCEEDED: - return "Quota on your Firebase Storage bucket has been exceeded."; - case StorageException.ERROR_NOT_AUTHENTICATED: - return "User is unauthenticated. Authenticate and try again."; - case StorageException.ERROR_NOT_AUTHORIZED: - return "User is not authorized to perform the desired action."; - case StorageException.ERROR_RETRY_LIMIT_EXCEEDED: - return "The maximum time limit on an operation (upload, download, delete, etc.) has been exceeded."; - case StorageException.ERROR_INVALID_CHECKSUM: - return "File on the client does not match the checksum of the file received by the server."; - case StorageException.ERROR_CANCELED: - return "User cancelled the operation."; - case StorageException.ERROR_UNKNOWN: - default: - { - return "An unknown error occurred"; - } - } - } -} diff --git a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseStoragePlugin.java b/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseStoragePlugin.java deleted file mode 100755 index 916fc6968eeb..000000000000 --- a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseStoragePlugin.java +++ /dev/null @@ -1,719 +0,0 @@ -// Copyright 2021 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package io.flutter.plugins.firebase.storage; - -import android.net.Uri; -import android.util.Base64; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import com.google.android.gms.tasks.Task; -import com.google.android.gms.tasks.TaskCompletionSource; -import com.google.firebase.FirebaseApp; -import com.google.firebase.storage.FirebaseStorage; -import com.google.firebase.storage.ListResult; -import com.google.firebase.storage.StorageMetadata; -import com.google.firebase.storage.StorageReference; -import io.flutter.embedding.engine.plugins.FlutterPlugin; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.EventChannel; -import io.flutter.plugin.common.EventChannel.StreamHandler; -import io.flutter.plugin.common.MethodChannel; -import io.flutter.plugins.firebase.core.FlutterFirebasePlugin; -import io.flutter.plugins.firebase.core.FlutterFirebasePluginRegistry; -import java.io.File; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; - -public class FlutterFirebaseStoragePlugin - implements FlutterFirebasePlugin, - FlutterPlugin, - GeneratedAndroidFirebaseStorage.FirebaseStorageHostApi { - - private MethodChannel channel; - @Nullable private BinaryMessenger messenger; - static final String STORAGE_METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_storage"; - static final String STORAGE_TASK_EVENT_NAME = "taskEvent"; - static final String DEFAULT_ERROR_CODE = "firebase_storage"; - - static final Map eventChannels = new HashMap<>(); - static final Map streamHandlers = new HashMap<>(); - - static Map getExceptionDetails(Exception exception) { - Map details = new HashMap<>(); - GeneratedAndroidFirebaseStorage.FlutterError storageException = - FlutterFirebaseStorageException.parserExceptionToFlutter(exception); - - details.put("code", storageException.code); - details.put("message", storageException.getMessage()); - - return details; - } - - static Map parseMetadataToMap(StorageMetadata storageMetadata) { - if (storageMetadata == null) { - return null; - } - - Map out = new HashMap<>(); - if (storageMetadata.getName() != null) { - out.put("name", storageMetadata.getName()); - } - - if (storageMetadata.getBucket() != null) { - out.put("bucket", storageMetadata.getBucket()); - } - - if (storageMetadata.getGeneration() != null) { - out.put("generation", storageMetadata.getGeneration()); - } - - if (storageMetadata.getMetadataGeneration() != null) { - out.put("metadataGeneration", storageMetadata.getMetadataGeneration()); - } - - out.put("fullPath", storageMetadata.getPath()); - - out.put("size", storageMetadata.getSizeBytes()); - - out.put("creationTimeMillis", storageMetadata.getCreationTimeMillis()); - - out.put("updatedTimeMillis", storageMetadata.getUpdatedTimeMillis()); - - if (storageMetadata.getMd5Hash() != null) { - out.put("md5Hash", storageMetadata.getMd5Hash()); - } - - if (storageMetadata.getCacheControl() != null) { - out.put("cacheControl", storageMetadata.getCacheControl()); - } - - if (storageMetadata.getContentDisposition() != null) { - out.put("contentDisposition", storageMetadata.getContentDisposition()); - } - - if (storageMetadata.getContentEncoding() != null) { - out.put("contentEncoding", storageMetadata.getContentEncoding()); - } - - if (storageMetadata.getContentLanguage() != null) { - out.put("contentLanguage", storageMetadata.getContentLanguage()); - } - - if (storageMetadata.getContentType() != null) { - out.put("contentType", storageMetadata.getContentType()); - } - - Map customMetadata = new HashMap<>(); - for (String key : storageMetadata.getCustomMetadataKeys()) { - if (storageMetadata.getCustomMetadata(key) == null) { - customMetadata.put(key, ""); - } else { - customMetadata.put(key, Objects.requireNonNull(storageMetadata.getCustomMetadata(key))); - } - } - out.put("customMetadata", customMetadata); - return out; - } - - @Override - public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { - initInstance(binding.getBinaryMessenger()); - } - - @Override - public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { - FlutterFirebaseStorageTask.cancelInProgressTasks(); - channel.setMethodCallHandler(null); - assert messenger != null; - GeneratedAndroidFirebaseStorage.FirebaseStorageHostApi.setup(messenger, null); - channel = null; - messenger = null; - removeEventListeners(); - } - - private void initInstance(BinaryMessenger messenger) { - FlutterFirebasePluginRegistry.registerPlugin(STORAGE_METHOD_CHANNEL_NAME, this); - channel = new MethodChannel(messenger, STORAGE_METHOD_CHANNEL_NAME); - GeneratedAndroidFirebaseStorage.FirebaseStorageHostApi.setup(messenger, this); - this.messenger = messenger; - } - - private String registerEventChannel(String prefix, String identifier, StreamHandler handler) { - final String channelName = prefix + "/" + identifier; - - EventChannel channel = new EventChannel(messenger, channelName); - channel.setStreamHandler(handler); - eventChannels.put(identifier, channel); - streamHandlers.put(identifier, handler); - - return identifier; - } - - private synchronized void removeEventListeners() { - // Create a list to hold the keys to remove after iteration - List eventChannelKeys = new ArrayList<>(eventChannels.keySet()); - for (String identifier : eventChannelKeys) { - EventChannel eventChannel = eventChannels.get(identifier); - if (eventChannel != null) { - eventChannel.setStreamHandler(null); - } - eventChannels.remove(identifier); - } - - // Create a list to hold the keys to remove after iteration - List streamHandlerKeys = new ArrayList<>(streamHandlers.keySet()); - for (String identifier : streamHandlerKeys) { - StreamHandler streamHandler = streamHandlers.get(identifier); - if (streamHandler != null) { - streamHandler.onCancel(null); - } - streamHandlers.remove(identifier); - } - } - - private FirebaseStorage getStorageFromPigeon( - GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app) { - FirebaseApp androidApp = FirebaseApp.getInstance(app.getAppName()); - - return FirebaseStorage.getInstance(androidApp, "gs://" + app.getBucket()); - } - - private StorageReference getReferenceFromPigeon( - GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - GeneratedAndroidFirebaseStorage.PigeonStorageReference reference) { - FirebaseStorage androidStorage = getStorageFromPigeon(app); - return androidStorage.getReference(reference.getFullPath()); - } - - private GeneratedAndroidFirebaseStorage.PigeonStorageReference convertToPigeonReference( - StorageReference reference) { - return new GeneratedAndroidFirebaseStorage.PigeonStorageReference.Builder() - .setBucket(reference.getBucket()) - .setFullPath(reference.getPath()) - .setName(reference.getName()) - .build(); - } - - @Override - public void getReferencebyPath( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull String path, - @Nullable String bucket, - @NonNull - GeneratedAndroidFirebaseStorage.Result< - GeneratedAndroidFirebaseStorage.PigeonStorageReference> - result) { - StorageReference androidReference = getStorageFromPigeon(app).getReference(path); - - result.success(convertToPigeonReference(androidReference)); - } - - @Override - public void useStorageEmulator( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull String host, - @NonNull Long port, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - try { - FirebaseStorage androidStorage = getStorageFromPigeon(app); - androidStorage.useEmulator(host, port.intValue()); - result.success(null); - } catch (Exception e) { - result.error(FlutterFirebaseStorageException.parserExceptionToFlutter(e)); - } - } - - // FirebaseStorageHostApi Reference related api override - @Override - public void referenceDelete( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - FirebaseStorage firebaseStorage = getStorageFromPigeon(app); - StorageReference androidReference = firebaseStorage.getReference(reference.getFullPath()); - androidReference - .delete() - .addOnCompleteListener( - task -> { - if (task.isSuccessful()) { - result.success(null); - } else { - result.error( - FlutterFirebaseStorageException.parserExceptionToFlutter(task.getException())); - } - }); - } - - @Override - public void referenceGetDownloadURL( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - FirebaseStorage firebaseStorage = getStorageFromPigeon(app); - - StorageReference androidReference = firebaseStorage.getReference(reference.getFullPath()); - androidReference - .getDownloadUrl() - .addOnCompleteListener( - task -> { - if (task.isSuccessful()) { - Uri androidUrl = task.getResult(); - result.success(androidUrl.toString()); - } else { - result.error( - FlutterFirebaseStorageException.parserExceptionToFlutter(task.getException())); - } - }); - } - - @Override - public void referenceGetData( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull Long maxSize, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - FirebaseStorage firebaseStorage = getStorageFromPigeon(app); - StorageReference androidReference = firebaseStorage.getReference(reference.getFullPath()); - androidReference - .getBytes(maxSize) - .addOnCompleteListener( - task -> { - if (task.isSuccessful()) { - byte[] androidData = task.getResult(); - result.success(androidData); - } else { - result.error( - FlutterFirebaseStorageException.parserExceptionToFlutter(task.getException())); - } - }); - } - - GeneratedAndroidFirebaseStorage.PigeonFullMetaData convertToPigeonMetaData( - StorageMetadata meteData) { - return new GeneratedAndroidFirebaseStorage.PigeonFullMetaData.Builder() - .setMetadata(parseMetadataToMap(meteData)) - .build(); - } - - @Override - public void referenceGetMetaData( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull - GeneratedAndroidFirebaseStorage.Result - result) { - FirebaseStorage firebaseStorage = getStorageFromPigeon(app); - StorageReference androidReference = firebaseStorage.getReference(reference.getFullPath()); - androidReference - .getMetadata() - .addOnCompleteListener( - task -> { - if (task.isSuccessful()) { - StorageMetadata androidMetaData = task.getResult(); - result.success(convertToPigeonMetaData(androidMetaData)); - } else { - result.error( - FlutterFirebaseStorageException.parserExceptionToFlutter(task.getException())); - } - }); - } - - GeneratedAndroidFirebaseStorage.PigeonListResult convertToPigeonListResult( - ListResult listResult) { - List pigeonItems = new ArrayList<>(); - for (StorageReference storageReference : listResult.getItems()) { - pigeonItems.add(convertToPigeonReference(storageReference)); - } - List pigeonPrefixes = new ArrayList<>(); - for (StorageReference storageReference : listResult.getPrefixes()) { - pigeonPrefixes.add(convertToPigeonReference(storageReference)); - } - return new GeneratedAndroidFirebaseStorage.PigeonListResult.Builder() - .setItems(pigeonItems) - .setPageToken(listResult.getPageToken()) - .setPrefixs(pigeonPrefixes) - .build(); - } - - @Override - public void referenceList( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull GeneratedAndroidFirebaseStorage.PigeonListOptions options, - @NonNull - GeneratedAndroidFirebaseStorage.Result - result) { - FirebaseStorage firebaseStorage = getStorageFromPigeon(app); - StorageReference androidReference = firebaseStorage.getReference(reference.getFullPath()); - Task androidResult; - if (options.getPageToken() != null) { - androidResult = - androidReference.list(options.getMaxResults().intValue(), options.getPageToken()); - } else { - androidResult = androidReference.list(options.getMaxResults().intValue()); - } - androidResult.addOnCompleteListener( - task -> { - if (task.isSuccessful()) { - ListResult androidListResult = task.getResult(); - result.success(convertToPigeonListResult(androidListResult)); - } else { - result.error( - FlutterFirebaseStorageException.parserExceptionToFlutter(task.getException())); - } - }); - } - - @Override - public void referenceListAll( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull - GeneratedAndroidFirebaseStorage.Result - result) { - FirebaseStorage firebaseStorage = getStorageFromPigeon(app); - StorageReference androidReference = firebaseStorage.getReference(reference.getFullPath()); - androidReference - .listAll() - .addOnCompleteListener( - task -> { - if (task.isSuccessful()) { - ListResult androidListResult = task.getResult(); - result.success(convertToPigeonListResult(androidListResult)); - } else { - result.error( - FlutterFirebaseStorageException.parserExceptionToFlutter(task.getException())); - } - }); - } - - StorageMetadata getMetaDataFromPigeon( - GeneratedAndroidFirebaseStorage.PigeonSettableMetadata pigeonSettableMetatdata) { - StorageMetadata.Builder androidMetaDataBuilder = new StorageMetadata.Builder(); - - if (pigeonSettableMetatdata.getContentType() != null) { - androidMetaDataBuilder.setContentType(pigeonSettableMetatdata.getContentType()); - } - if (pigeonSettableMetatdata.getCacheControl() != null) { - androidMetaDataBuilder.setCacheControl(pigeonSettableMetatdata.getCacheControl()); - } - if (pigeonSettableMetatdata.getContentDisposition() != null) { - androidMetaDataBuilder.setContentDisposition(pigeonSettableMetatdata.getContentDisposition()); - } - if (pigeonSettableMetatdata.getContentEncoding() != null) { - androidMetaDataBuilder.setContentEncoding(pigeonSettableMetatdata.getContentEncoding()); - } - if (pigeonSettableMetatdata.getContentLanguage() != null) { - androidMetaDataBuilder.setContentLanguage(pigeonSettableMetatdata.getContentLanguage()); - } - - Map pigeonCustomMetadata = pigeonSettableMetatdata.getCustomMetadata(); - if (pigeonCustomMetadata != null) { - for (Map.Entry entry : pigeonCustomMetadata.entrySet()) { - androidMetaDataBuilder.setCustomMetadata(entry.getKey(), entry.getValue()); - } - } - - return androidMetaDataBuilder.build(); - } - - @Override - public void referenceUpdateMetadata( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull GeneratedAndroidFirebaseStorage.PigeonSettableMetadata metadata, - @NonNull - GeneratedAndroidFirebaseStorage.Result - result) { - FirebaseStorage firebaseStorage = getStorageFromPigeon(app); - StorageReference androidReference = firebaseStorage.getReference(reference.getFullPath()); - androidReference - .updateMetadata(getMetaDataFromPigeon(metadata)) - .addOnCompleteListener( - task -> { - if (task.isSuccessful()) { - StorageMetadata androidMetadata = task.getResult(); - result.success(convertToPigeonMetaData(androidMetadata)); - } else { - result.error( - FlutterFirebaseStorageException.parserExceptionToFlutter(task.getException())); - } - }); - } - - @Override - public void referencePutData( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull byte[] data, - @NonNull GeneratedAndroidFirebaseStorage.PigeonSettableMetadata settableMetaData, - @NonNull Long handle, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - - StorageReference androidReference = getReferenceFromPigeon(app, reference); - StorageMetadata androidMetaData = getMetaDataFromPigeon(settableMetaData); - - FlutterFirebaseStorageTask storageTask = - FlutterFirebaseStorageTask.uploadBytes( - handle.intValue(), androidReference, data, androidMetaData); - try { - String identifier = UUID.randomUUID().toString().toLowerCase(Locale.US); - TaskStateChannelStreamHandler handler = - storageTask.startTaskWithMethodChannel(channel, identifier); - result.success( - registerEventChannel( - STORAGE_METHOD_CHANNEL_NAME + "/" + STORAGE_TASK_EVENT_NAME, identifier, handler)); - } catch (Exception e) { - result.error(FlutterFirebaseStorageException.parserExceptionToFlutter(e)); - } - } - - @Override - public void referencePutString( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull String data, - @NonNull Long format, - @NonNull GeneratedAndroidFirebaseStorage.PigeonSettableMetadata settableMetaData, - @NonNull Long handle, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - - StorageReference androidReference = getReferenceFromPigeon(app, reference); - StorageMetadata androidMetaData = getMetaDataFromPigeon(settableMetaData); - - FlutterFirebaseStorageTask storageTask = - FlutterFirebaseStorageTask.uploadBytes( - handle.intValue(), - androidReference, - stringToByteData(data, format.intValue()), - androidMetaData); - - try { - String identifier = UUID.randomUUID().toString().toLowerCase(Locale.US); - TaskStateChannelStreamHandler handler = - storageTask.startTaskWithMethodChannel(channel, identifier); - result.success( - registerEventChannel( - STORAGE_METHOD_CHANNEL_NAME + "/" + STORAGE_TASK_EVENT_NAME, identifier, handler)); - } catch (Exception e) { - result.error(FlutterFirebaseStorageException.parserExceptionToFlutter(e)); - } - } - - @Override - public void referencePutFile( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull String filePath, - @Nullable GeneratedAndroidFirebaseStorage.PigeonSettableMetadata settableMetaData, - @NonNull Long handle, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - - StorageReference androidReference = getReferenceFromPigeon(app, reference); - - FlutterFirebaseStorageTask storageTask = - FlutterFirebaseStorageTask.uploadFile( - handle.intValue(), - androidReference, - Uri.fromFile(new File(filePath)), - settableMetaData == null ? null : getMetaDataFromPigeon(settableMetaData)); - - try { - String identifier = UUID.randomUUID().toString().toLowerCase(Locale.US); - TaskStateChannelStreamHandler handler = - storageTask.startTaskWithMethodChannel(channel, identifier); - result.success( - registerEventChannel( - STORAGE_METHOD_CHANNEL_NAME + "/" + STORAGE_TASK_EVENT_NAME, identifier, handler)); - } catch (Exception e) { - result.error(FlutterFirebaseStorageException.parserExceptionToFlutter(e)); - } - } - - @Override - public void referenceDownloadFile( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageReference reference, - @NonNull String filePath, - @NonNull Long handle, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - - StorageReference androidReference = getReferenceFromPigeon(app, reference); - FlutterFirebaseStorageTask storageTask = - FlutterFirebaseStorageTask.downloadFile( - handle.intValue(), androidReference, new File(filePath)); - - try { - String identifier = UUID.randomUUID().toString().toLowerCase(Locale.US); - TaskStateChannelStreamHandler handler = - storageTask.startTaskWithMethodChannel(channel, identifier); - result.success( - registerEventChannel( - STORAGE_METHOD_CHANNEL_NAME + "/" + STORAGE_TASK_EVENT_NAME, identifier, handler)); - } catch (Exception e) { - result.error(FlutterFirebaseStorageException.parserExceptionToFlutter(e)); - } - } - - // FirebaseStorageHostApi Task related api override - @Override - public void taskPause( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull Long handle, - @NonNull GeneratedAndroidFirebaseStorage.Result> result) { - - FlutterFirebaseStorageTask storageTask = - FlutterFirebaseStorageTask.getInProgressTaskForHandle(handle.intValue()); - - if (storageTask == null) { - result.error( - new GeneratedAndroidFirebaseStorage.FlutterError( - "unknown", "Pause operation was called on a task which does not exist.", null)); - return; - } - - Map statusMap = new HashMap<>(); - try { - boolean paused = storageTask.getAndroidTask().pause(); - statusMap.put("status", paused); - if (paused) { - statusMap.put( - "snapshot", FlutterFirebaseStorageTask.parseTaskSnapshot(storageTask.getSnapshot())); - } - result.success(statusMap); - } catch (Exception e) { - result.error(FlutterFirebaseStorageException.parserExceptionToFlutter(e)); - } - } - - @Override - public void taskResume( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull Long handle, - @NonNull GeneratedAndroidFirebaseStorage.Result> result) { - - FlutterFirebaseStorageTask storageTask = - FlutterFirebaseStorageTask.getInProgressTaskForHandle(handle.intValue()); - - if (storageTask == null) { - result.error( - new GeneratedAndroidFirebaseStorage.FlutterError( - "unknown", "Resume operation was called on a task which does not exist.", null)); - return; - } - - try { - boolean resumed = storageTask.getAndroidTask().resume(); - Map statusMap = new HashMap<>(); - statusMap.put("status", resumed); - if (resumed) { - statusMap.put( - "snapshot", FlutterFirebaseStorageTask.parseTaskSnapshot(storageTask.getSnapshot())); - } - result.success(statusMap); - } catch (Exception e) { - result.error(FlutterFirebaseStorageException.parserExceptionToFlutter(e)); - } - } - - @Override - public void taskCancel( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull Long handle, - @NonNull GeneratedAndroidFirebaseStorage.Result> result) { - FlutterFirebaseStorageTask storageTask = - FlutterFirebaseStorageTask.getInProgressTaskForHandle(handle.intValue()); - if (storageTask == null) { - result.error( - new GeneratedAndroidFirebaseStorage.FlutterError( - "unknown", "Cancel operation was called on a task which does not exist.", null)); - return; - } - - try { - boolean canceled = storageTask.getAndroidTask().cancel(); - Map statusMap = new HashMap<>(); - statusMap.put("status", canceled); - if (canceled) { - statusMap.put( - "snapshot", FlutterFirebaseStorageTask.parseTaskSnapshot(storageTask.getSnapshot())); - } - result.success(statusMap); - } catch (Exception e) { - result.error(FlutterFirebaseStorageException.parserExceptionToFlutter(e)); - } - } - - @Override - public void setMaxOperationRetryTime( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull Long time, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - FirebaseStorage androidStorage = getStorageFromPigeon(app); - androidStorage.setMaxOperationRetryTimeMillis(time); - result.success(null); - } - - @Override - public void setMaxUploadRetryTime( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull Long time, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - FirebaseStorage androidStorage = getStorageFromPigeon(app); - androidStorage.setMaxUploadRetryTimeMillis(time); - result.success(null); - } - - @Override - public void setMaxDownloadRetryTime( - @NonNull GeneratedAndroidFirebaseStorage.PigeonStorageFirebaseApp app, - @NonNull Long time, - @NonNull GeneratedAndroidFirebaseStorage.Result result) { - FirebaseStorage androidStorage = getStorageFromPigeon(app); - androidStorage.setMaxDownloadRetryTimeMillis(time); - result.success(null); - } - - private byte[] stringToByteData(@NonNull String data, int format) { - switch (format) { - case 1: // PutStringFormat.base64 - return Base64.decode(data, Base64.DEFAULT); - case 2: // PutStringFormat.base64Url - return Base64.decode(data, Base64.URL_SAFE); - default: - return null; - } - } - - @Override - public Task> getPluginConstantsForFirebaseApp(FirebaseApp firebaseApp) { - TaskCompletionSource> taskCompletionSource = new TaskCompletionSource<>(); - cachedThreadPool.execute( - () -> { - HashMap obj = new HashMap(); - taskCompletionSource.setResult(obj); - }); - - return taskCompletionSource.getTask(); - } - - @Override - public Task didReinitializeFirebaseCore() { - TaskCompletionSource taskCompletionSource = new TaskCompletionSource<>(); - cachedThreadPool.execute( - () -> { - FlutterFirebaseStorageTask.cancelInProgressTasks(); - taskCompletionSource.setResult(null); - removeEventListeners(); - }); - - return taskCompletionSource.getTask(); - } -} diff --git a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageTask.java b/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageTask.java deleted file mode 100644 index 42b3baebaa64..000000000000 --- a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageTask.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2022, the Chromium project authors. Please see the AUTHORS file - * for details. All rights reserved. Use of this source code is governed by a - * BSD-style license that can be found in the LICENSE file. - */ - -package io.flutter.plugins.firebase.storage; - -import static io.flutter.plugins.firebase.storage.FlutterFirebaseStoragePlugin.parseMetadataToMap; - -import android.net.Uri; -import android.util.SparseArray; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import com.google.firebase.storage.FileDownloadTask; -import com.google.firebase.storage.StorageMetadata; -import com.google.firebase.storage.StorageReference; -import com.google.firebase.storage.StorageTask; -import com.google.firebase.storage.UploadTask; -import io.flutter.plugin.common.MethodChannel; -import java.io.File; -import java.util.HashMap; -import java.util.Map; - -class FlutterFirebaseStorageTask { - static final SparseArray inProgressTasks = new SparseArray<>(); - private final FlutterFirebaseStorageTaskType type; - private final int handle; - private final StorageReference reference; - private final byte[] bytes; - private final Uri fileUri; - private final StorageMetadata metadata; - private final Object pauseSyncObject = new Object(); - private final Object resumeSyncObject = new Object(); - private final Object cancelSyncObject = new Object(); - private StorageTask storageTask; - private Boolean destroyed = false; - - private FlutterFirebaseStorageTask( - FlutterFirebaseStorageTaskType type, - int handle, - StorageReference reference, - @Nullable byte[] bytes, - @Nullable Uri fileUri, - @Nullable StorageMetadata metadata) { - this.type = type; - this.handle = handle; - this.reference = reference; - this.bytes = bytes; - this.fileUri = fileUri; - this.metadata = metadata; - synchronized (inProgressTasks) { - inProgressTasks.put(handle, this); - } - } - - @Nullable - static FlutterFirebaseStorageTask getInProgressTaskForHandle(int handle) { - synchronized (inProgressTasks) { - return inProgressTasks.get(handle); - } - } - - static void cancelInProgressTasks() { - synchronized (inProgressTasks) { - for (int i = 0; i < inProgressTasks.size(); i++) { - FlutterFirebaseStorageTask task = null; - task = inProgressTasks.valueAt(i); - if (task != null) { - task.destroy(); - } - } - - inProgressTasks.clear(); - } - } - - public static FlutterFirebaseStorageTask uploadBytes( - int handle, StorageReference reference, byte[] data, @Nullable StorageMetadata metadata) { - return new FlutterFirebaseStorageTask( - FlutterFirebaseStorageTaskType.BYTES, handle, reference, data, null, metadata); - } - - public static FlutterFirebaseStorageTask uploadFile( - int handle, - StorageReference reference, - @NonNull Uri fileUri, - @Nullable StorageMetadata metadata) { - return new FlutterFirebaseStorageTask( - FlutterFirebaseStorageTaskType.FILE, handle, reference, null, fileUri, metadata); - } - - public static FlutterFirebaseStorageTask downloadFile( - int handle, StorageReference reference, @NonNull File file) { - return new FlutterFirebaseStorageTask( - FlutterFirebaseStorageTaskType.DOWNLOAD, handle, reference, null, Uri.fromFile(file), null); - } - - public static Map parseUploadTaskSnapshot(UploadTask.TaskSnapshot snapshot) { - Map out = new HashMap<>(); - out.put("path", snapshot.getStorage().getPath()); - out.put("bytesTransferred", snapshot.getBytesTransferred()); - out.put("totalBytes", snapshot.getTotalByteCount()); - if (snapshot.getMetadata() != null) { - out.put("metadata", parseMetadataToMap(snapshot.getMetadata())); - } - return out; - } - - public static Map parseDownloadTaskSnapshot( - FileDownloadTask.TaskSnapshot snapshot) { - Map out = new HashMap<>(); - out.put("path", snapshot.getStorage().getPath()); - if (snapshot.getTask().isSuccessful()) { - // TODO(Salakar): work around a bug on the Firebase Android SDK where - // sometimes `getBytesTransferred` != `getTotalByteCount` even - // when download has completed. - out.put("bytesTransferred", snapshot.getTotalByteCount()); - } else { - out.put("bytesTransferred", snapshot.getBytesTransferred()); - } - out.put("totalBytes", snapshot.getTotalByteCount()); - return out; - } - - static Map parseTaskSnapshot(Object snapshot) { - if (snapshot instanceof FileDownloadTask.TaskSnapshot) { - return parseDownloadTaskSnapshot((FileDownloadTask.TaskSnapshot) snapshot); - } else { - return parseUploadTaskSnapshot((UploadTask.TaskSnapshot) snapshot); - } - } - - void destroy() { - if (destroyed) return; - destroyed = true; - - synchronized (inProgressTasks) { - if (storageTask.isInProgress() || storageTask.isPaused()) { - storageTask.cancel(); - } - inProgressTasks.remove(handle); - } - - synchronized (cancelSyncObject) { - cancelSyncObject.notifyAll(); - } - - synchronized (pauseSyncObject) { - pauseSyncObject.notifyAll(); - } - - synchronized (resumeSyncObject) { - resumeSyncObject.notifyAll(); - } - } - - TaskStateChannelStreamHandler startTaskWithMethodChannel( - @NonNull MethodChannel channel, @NonNull String identifier) throws Exception { - if (type == FlutterFirebaseStorageTaskType.BYTES && bytes != null) { - if (metadata == null) { - storageTask = reference.putBytes(bytes); - } else { - storageTask = reference.putBytes(bytes, metadata); - } - } else if (type == FlutterFirebaseStorageTaskType.FILE && fileUri != null) { - if (metadata == null) { - storageTask = reference.putFile(fileUri); - } else { - storageTask = reference.putFile(fileUri, metadata); - } - } else if (type == FlutterFirebaseStorageTaskType.DOWNLOAD && fileUri != null) { - storageTask = reference.getFile(fileUri); - } else { - throw new Exception("Unable to start task. Some arguments have no been initialized."); - } - - return new TaskStateChannelStreamHandler(this, reference.getStorage(), storageTask, identifier); - } - - public Object getSnapshot() { - return storageTask.getSnapshot(); - } - - public boolean isDestroyed() { - return destroyed; - } - - public void notifyResumeObjects() { - synchronized (resumeSyncObject) { - resumeSyncObject.notifyAll(); - } - } - - public void notifyCancelObjects() { - synchronized (cancelSyncObject) { - cancelSyncObject.notifyAll(); - } - } - - public void notifyPauseObjects() { - synchronized (pauseSyncObject) { - pauseSyncObject.notifyAll(); - } - } - - public StorageTask getAndroidTask() { - return storageTask; - } - - private enum FlutterFirebaseStorageTaskType { - FILE, - BYTES, - DOWNLOAD, - } -} diff --git a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/GeneratedAndroidFirebaseStorage.java b/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/GeneratedAndroidFirebaseStorage.java deleted file mode 100644 index d3a167febc03..000000000000 --- a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/GeneratedAndroidFirebaseStorage.java +++ /dev/null @@ -1,1506 +0,0 @@ -// Copyright 2023, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -// Autogenerated from Pigeon (v11.0.1), do not edit directly. -// See also: https://pub.dev/packages/pigeon - -package io.flutter.plugins.firebase.storage; - -import android.util.Log; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import io.flutter.plugin.common.BasicMessageChannel; -import io.flutter.plugin.common.BinaryMessenger; -import io.flutter.plugin.common.MessageCodec; -import io.flutter.plugin.common.StandardMessageCodec; -import java.io.ByteArrayOutputStream; -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -/** Generated class from Pigeon. */ -@SuppressWarnings({"unused", "unchecked", "CodeBlock2Expr", "RedundantSuppression", "serial"}) -public class GeneratedAndroidFirebaseStorage { - - /** Error class for passing custom error details to Flutter via a thrown PlatformException. */ - public static class FlutterError extends RuntimeException { - - /** The error code. */ - public final String code; - - /** The error details. Must be a datatype supported by the api codec. */ - public final Object details; - - public FlutterError(@NonNull String code, @Nullable String message, @Nullable Object details) { - super(message); - this.code = code; - this.details = details; - } - } - - @NonNull - protected static ArrayList wrapError(@NonNull Throwable exception) { - ArrayList errorList = new ArrayList(3); - if (exception instanceof FlutterError) { - FlutterError error = (FlutterError) exception; - errorList.add(error.code); - errorList.add(error.getMessage()); - errorList.add(error.details); - } else { - errorList.add(exception.toString()); - errorList.add(exception.getClass().getSimpleName()); - errorList.add( - "Cause: " + exception.getCause() + ", Stacktrace: " + Log.getStackTraceString(exception)); - } - return errorList; - } - - /** The type of operation that generated the action code from calling [TaskState]. */ - public enum PigeonStorageTaskState { - /** Indicates the task has been paused by the user. */ - PAUSED(0), - /** Indicates the task is currently in-progress. */ - RUNNING(1), - /** Indicates the task has successfully completed. */ - SUCCESS(2), - /** Indicates the task was canceled. */ - CANCELED(3), - /** Indicates the task failed with an error. */ - ERROR(4); - - final int index; - - private PigeonStorageTaskState(final int index) { - this.index = index; - } - } - - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class PigeonStorageFirebaseApp { - private @NonNull String appName; - - public @NonNull String getAppName() { - return appName; - } - - public void setAppName(@NonNull String setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"appName\" is null."); - } - this.appName = setterArg; - } - - private @Nullable String tenantId; - - public @Nullable String getTenantId() { - return tenantId; - } - - public void setTenantId(@Nullable String setterArg) { - this.tenantId = setterArg; - } - - private @NonNull String bucket; - - public @NonNull String getBucket() { - return bucket; - } - - public void setBucket(@NonNull String setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"bucket\" is null."); - } - this.bucket = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - PigeonStorageFirebaseApp() {} - - public static final class Builder { - - private @Nullable String appName; - - public @NonNull Builder setAppName(@NonNull String setterArg) { - this.appName = setterArg; - return this; - } - - private @Nullable String tenantId; - - public @NonNull Builder setTenantId(@Nullable String setterArg) { - this.tenantId = setterArg; - return this; - } - - private @Nullable String bucket; - - public @NonNull Builder setBucket(@NonNull String setterArg) { - this.bucket = setterArg; - return this; - } - - public @NonNull PigeonStorageFirebaseApp build() { - PigeonStorageFirebaseApp pigeonReturn = new PigeonStorageFirebaseApp(); - pigeonReturn.setAppName(appName); - pigeonReturn.setTenantId(tenantId); - pigeonReturn.setBucket(bucket); - return pigeonReturn; - } - } - - @NonNull - public ArrayList toList() { - ArrayList toListResult = new ArrayList(3); - toListResult.add(appName); - toListResult.add(tenantId); - toListResult.add(bucket); - return toListResult; - } - - static @NonNull PigeonStorageFirebaseApp fromList(@NonNull ArrayList list) { - PigeonStorageFirebaseApp pigeonResult = new PigeonStorageFirebaseApp(); - Object appName = list.get(0); - pigeonResult.setAppName((String) appName); - Object tenantId = list.get(1); - pigeonResult.setTenantId((String) tenantId); - Object bucket = list.get(2); - pigeonResult.setBucket((String) bucket); - return pigeonResult; - } - } - - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class PigeonStorageReference { - private @NonNull String bucket; - - public @NonNull String getBucket() { - return bucket; - } - - public void setBucket(@NonNull String setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"bucket\" is null."); - } - this.bucket = setterArg; - } - - private @NonNull String fullPath; - - public @NonNull String getFullPath() { - return fullPath; - } - - public void setFullPath(@NonNull String setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"fullPath\" is null."); - } - this.fullPath = setterArg; - } - - private @NonNull String name; - - public @NonNull String getName() { - return name; - } - - public void setName(@NonNull String setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"name\" is null."); - } - this.name = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - PigeonStorageReference() {} - - public static final class Builder { - - private @Nullable String bucket; - - public @NonNull Builder setBucket(@NonNull String setterArg) { - this.bucket = setterArg; - return this; - } - - private @Nullable String fullPath; - - public @NonNull Builder setFullPath(@NonNull String setterArg) { - this.fullPath = setterArg; - return this; - } - - private @Nullable String name; - - public @NonNull Builder setName(@NonNull String setterArg) { - this.name = setterArg; - return this; - } - - public @NonNull PigeonStorageReference build() { - PigeonStorageReference pigeonReturn = new PigeonStorageReference(); - pigeonReturn.setBucket(bucket); - pigeonReturn.setFullPath(fullPath); - pigeonReturn.setName(name); - return pigeonReturn; - } - } - - @NonNull - public ArrayList toList() { - ArrayList toListResult = new ArrayList(3); - toListResult.add(bucket); - toListResult.add(fullPath); - toListResult.add(name); - return toListResult; - } - - static @NonNull PigeonStorageReference fromList(@NonNull ArrayList list) { - PigeonStorageReference pigeonResult = new PigeonStorageReference(); - Object bucket = list.get(0); - pigeonResult.setBucket((String) bucket); - Object fullPath = list.get(1); - pigeonResult.setFullPath((String) fullPath); - Object name = list.get(2); - pigeonResult.setName((String) name); - return pigeonResult; - } - } - - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class PigeonFullMetaData { - private @Nullable Map metadata; - - public @Nullable Map getMetadata() { - return metadata; - } - - public void setMetadata(@Nullable Map setterArg) { - this.metadata = setterArg; - } - - public static final class Builder { - - private @Nullable Map metadata; - - public @NonNull Builder setMetadata(@Nullable Map setterArg) { - this.metadata = setterArg; - return this; - } - - public @NonNull PigeonFullMetaData build() { - PigeonFullMetaData pigeonReturn = new PigeonFullMetaData(); - pigeonReturn.setMetadata(metadata); - return pigeonReturn; - } - } - - @NonNull - public ArrayList toList() { - ArrayList toListResult = new ArrayList(1); - toListResult.add(metadata); - return toListResult; - } - - static @NonNull PigeonFullMetaData fromList(@NonNull ArrayList list) { - PigeonFullMetaData pigeonResult = new PigeonFullMetaData(); - Object metadata = list.get(0); - pigeonResult.setMetadata((Map) metadata); - return pigeonResult; - } - } - - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class PigeonListOptions { - /** - * If set, limits the total number of `prefixes` and `items` to return. - * - *

The default and maximum maxResults is 1000. - */ - private @NonNull Long maxResults; - - public @NonNull Long getMaxResults() { - return maxResults; - } - - public void setMaxResults(@NonNull Long setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"maxResults\" is null."); - } - this.maxResults = setterArg; - } - - /** - * The nextPageToken from a previous call to list(). - * - *

If provided, listing is resumed from the previous position. - */ - private @Nullable String pageToken; - - public @Nullable String getPageToken() { - return pageToken; - } - - public void setPageToken(@Nullable String setterArg) { - this.pageToken = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - PigeonListOptions() {} - - public static final class Builder { - - private @Nullable Long maxResults; - - public @NonNull Builder setMaxResults(@NonNull Long setterArg) { - this.maxResults = setterArg; - return this; - } - - private @Nullable String pageToken; - - public @NonNull Builder setPageToken(@Nullable String setterArg) { - this.pageToken = setterArg; - return this; - } - - public @NonNull PigeonListOptions build() { - PigeonListOptions pigeonReturn = new PigeonListOptions(); - pigeonReturn.setMaxResults(maxResults); - pigeonReturn.setPageToken(pageToken); - return pigeonReturn; - } - } - - @NonNull - public ArrayList toList() { - ArrayList toListResult = new ArrayList(2); - toListResult.add(maxResults); - toListResult.add(pageToken); - return toListResult; - } - - static @NonNull PigeonListOptions fromList(@NonNull ArrayList list) { - PigeonListOptions pigeonResult = new PigeonListOptions(); - Object maxResults = list.get(0); - pigeonResult.setMaxResults( - (maxResults == null) - ? null - : ((maxResults instanceof Integer) ? (Integer) maxResults : (Long) maxResults)); - Object pageToken = list.get(1); - pigeonResult.setPageToken((String) pageToken); - return pigeonResult; - } - } - - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class PigeonSettableMetadata { - /** - * Served as the 'Cache-Control' header on object download. - * - *

See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control. - */ - private @Nullable String cacheControl; - - public @Nullable String getCacheControl() { - return cacheControl; - } - - public void setCacheControl(@Nullable String setterArg) { - this.cacheControl = setterArg; - } - - /** - * Served as the 'Content-Disposition' header on object download. - * - *

See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition. - */ - private @Nullable String contentDisposition; - - public @Nullable String getContentDisposition() { - return contentDisposition; - } - - public void setContentDisposition(@Nullable String setterArg) { - this.contentDisposition = setterArg; - } - - /** - * Served as the 'Content-Encoding' header on object download. - * - *

See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding. - */ - private @Nullable String contentEncoding; - - public @Nullable String getContentEncoding() { - return contentEncoding; - } - - public void setContentEncoding(@Nullable String setterArg) { - this.contentEncoding = setterArg; - } - - /** - * Served as the 'Content-Language' header on object download. - * - *

See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language. - */ - private @Nullable String contentLanguage; - - public @Nullable String getContentLanguage() { - return contentLanguage; - } - - public void setContentLanguage(@Nullable String setterArg) { - this.contentLanguage = setterArg; - } - - /** - * Served as the 'Content-Type' header on object download. - * - *

See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type. - */ - private @Nullable String contentType; - - public @Nullable String getContentType() { - return contentType; - } - - public void setContentType(@Nullable String setterArg) { - this.contentType = setterArg; - } - - /** Additional user-defined custom metadata. */ - private @Nullable Map customMetadata; - - public @Nullable Map getCustomMetadata() { - return customMetadata; - } - - public void setCustomMetadata(@Nullable Map setterArg) { - this.customMetadata = setterArg; - } - - public static final class Builder { - - private @Nullable String cacheControl; - - public @NonNull Builder setCacheControl(@Nullable String setterArg) { - this.cacheControl = setterArg; - return this; - } - - private @Nullable String contentDisposition; - - public @NonNull Builder setContentDisposition(@Nullable String setterArg) { - this.contentDisposition = setterArg; - return this; - } - - private @Nullable String contentEncoding; - - public @NonNull Builder setContentEncoding(@Nullable String setterArg) { - this.contentEncoding = setterArg; - return this; - } - - private @Nullable String contentLanguage; - - public @NonNull Builder setContentLanguage(@Nullable String setterArg) { - this.contentLanguage = setterArg; - return this; - } - - private @Nullable String contentType; - - public @NonNull Builder setContentType(@Nullable String setterArg) { - this.contentType = setterArg; - return this; - } - - private @Nullable Map customMetadata; - - public @NonNull Builder setCustomMetadata(@Nullable Map setterArg) { - this.customMetadata = setterArg; - return this; - } - - public @NonNull PigeonSettableMetadata build() { - PigeonSettableMetadata pigeonReturn = new PigeonSettableMetadata(); - pigeonReturn.setCacheControl(cacheControl); - pigeonReturn.setContentDisposition(contentDisposition); - pigeonReturn.setContentEncoding(contentEncoding); - pigeonReturn.setContentLanguage(contentLanguage); - pigeonReturn.setContentType(contentType); - pigeonReturn.setCustomMetadata(customMetadata); - return pigeonReturn; - } - } - - @NonNull - public ArrayList toList() { - ArrayList toListResult = new ArrayList(6); - toListResult.add(cacheControl); - toListResult.add(contentDisposition); - toListResult.add(contentEncoding); - toListResult.add(contentLanguage); - toListResult.add(contentType); - toListResult.add(customMetadata); - return toListResult; - } - - static @NonNull PigeonSettableMetadata fromList(@NonNull ArrayList list) { - PigeonSettableMetadata pigeonResult = new PigeonSettableMetadata(); - Object cacheControl = list.get(0); - pigeonResult.setCacheControl((String) cacheControl); - Object contentDisposition = list.get(1); - pigeonResult.setContentDisposition((String) contentDisposition); - Object contentEncoding = list.get(2); - pigeonResult.setContentEncoding((String) contentEncoding); - Object contentLanguage = list.get(3); - pigeonResult.setContentLanguage((String) contentLanguage); - Object contentType = list.get(4); - pigeonResult.setContentType((String) contentType); - Object customMetadata = list.get(5); - pigeonResult.setCustomMetadata((Map) customMetadata); - return pigeonResult; - } - } - - /** Generated class from Pigeon that represents data sent in messages. */ - public static final class PigeonListResult { - private @NonNull List items; - - public @NonNull List getItems() { - return items; - } - - public void setItems(@NonNull List setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"items\" is null."); - } - this.items = setterArg; - } - - private @Nullable String pageToken; - - public @Nullable String getPageToken() { - return pageToken; - } - - public void setPageToken(@Nullable String setterArg) { - this.pageToken = setterArg; - } - - private @NonNull List prefixs; - - public @NonNull List getPrefixs() { - return prefixs; - } - - public void setPrefixs(@NonNull List setterArg) { - if (setterArg == null) { - throw new IllegalStateException("Nonnull field \"prefixs\" is null."); - } - this.prefixs = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - PigeonListResult() {} - - public static final class Builder { - - private @Nullable List items; - - public @NonNull Builder setItems(@NonNull List setterArg) { - this.items = setterArg; - return this; - } - - private @Nullable String pageToken; - - public @NonNull Builder setPageToken(@Nullable String setterArg) { - this.pageToken = setterArg; - return this; - } - - private @Nullable List prefixs; - - public @NonNull Builder setPrefixs(@NonNull List setterArg) { - this.prefixs = setterArg; - return this; - } - - public @NonNull PigeonListResult build() { - PigeonListResult pigeonReturn = new PigeonListResult(); - pigeonReturn.setItems(items); - pigeonReturn.setPageToken(pageToken); - pigeonReturn.setPrefixs(prefixs); - return pigeonReturn; - } - } - - @NonNull - public ArrayList toList() { - ArrayList toListResult = new ArrayList(3); - toListResult.add(items); - toListResult.add(pageToken); - toListResult.add(prefixs); - return toListResult; - } - - static @NonNull PigeonListResult fromList(@NonNull ArrayList list) { - PigeonListResult pigeonResult = new PigeonListResult(); - Object items = list.get(0); - pigeonResult.setItems((List) items); - Object pageToken = list.get(1); - pigeonResult.setPageToken((String) pageToken); - Object prefixs = list.get(2); - pigeonResult.setPrefixs((List) prefixs); - return pigeonResult; - } - } - - public interface Result { - @SuppressWarnings("UnknownNullness") - void success(T result); - - void error(@NonNull Throwable error); - } - - private static class FirebaseStorageHostApiCodec extends StandardMessageCodec { - public static final FirebaseStorageHostApiCodec INSTANCE = new FirebaseStorageHostApiCodec(); - - private FirebaseStorageHostApiCodec() {} - - @Override - protected Object readValueOfType(byte type, @NonNull ByteBuffer buffer) { - switch (type) { - case (byte) 128: - return PigeonFullMetaData.fromList((ArrayList) readValue(buffer)); - case (byte) 129: - return PigeonListOptions.fromList((ArrayList) readValue(buffer)); - case (byte) 130: - return PigeonListResult.fromList((ArrayList) readValue(buffer)); - case (byte) 131: - return PigeonSettableMetadata.fromList((ArrayList) readValue(buffer)); - case (byte) 132: - return PigeonStorageFirebaseApp.fromList((ArrayList) readValue(buffer)); - case (byte) 133: - return PigeonStorageReference.fromList((ArrayList) readValue(buffer)); - default: - return super.readValueOfType(type, buffer); - } - } - - @Override - protected void writeValue(@NonNull ByteArrayOutputStream stream, Object value) { - if (value instanceof PigeonFullMetaData) { - stream.write(128); - writeValue(stream, ((PigeonFullMetaData) value).toList()); - } else if (value instanceof PigeonListOptions) { - stream.write(129); - writeValue(stream, ((PigeonListOptions) value).toList()); - } else if (value instanceof PigeonListResult) { - stream.write(130); - writeValue(stream, ((PigeonListResult) value).toList()); - } else if (value instanceof PigeonSettableMetadata) { - stream.write(131); - writeValue(stream, ((PigeonSettableMetadata) value).toList()); - } else if (value instanceof PigeonStorageFirebaseApp) { - stream.write(132); - writeValue(stream, ((PigeonStorageFirebaseApp) value).toList()); - } else if (value instanceof PigeonStorageReference) { - stream.write(133); - writeValue(stream, ((PigeonStorageReference) value).toList()); - } else { - super.writeValue(stream, value); - } - } - } - - /** Generated interface from Pigeon that represents a handler of messages from Flutter. */ - public interface FirebaseStorageHostApi { - - void getReferencebyPath( - @NonNull PigeonStorageFirebaseApp app, - @NonNull String path, - @Nullable String bucket, - @NonNull Result result); - - void setMaxOperationRetryTime( - @NonNull PigeonStorageFirebaseApp app, @NonNull Long time, @NonNull Result result); - - void setMaxUploadRetryTime( - @NonNull PigeonStorageFirebaseApp app, @NonNull Long time, @NonNull Result result); - - void setMaxDownloadRetryTime( - @NonNull PigeonStorageFirebaseApp app, @NonNull Long time, @NonNull Result result); - - void useStorageEmulator( - @NonNull PigeonStorageFirebaseApp app, - @NonNull String host, - @NonNull Long port, - @NonNull Result result); - - void referenceDelete( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull Result result); - - void referenceGetDownloadURL( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull Result result); - - void referenceGetMetaData( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull Result result); - - void referenceList( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull PigeonListOptions options, - @NonNull Result result); - - void referenceListAll( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull Result result); - - void referenceGetData( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull Long maxSize, - @NonNull Result result); - - void referencePutData( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull byte[] data, - @NonNull PigeonSettableMetadata settableMetaData, - @NonNull Long handle, - @NonNull Result result); - - void referencePutString( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull String data, - @NonNull Long format, - @NonNull PigeonSettableMetadata settableMetaData, - @NonNull Long handle, - @NonNull Result result); - - void referencePutFile( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull String filePath, - @Nullable PigeonSettableMetadata settableMetaData, - @NonNull Long handle, - @NonNull Result result); - - void referenceDownloadFile( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull String filePath, - @NonNull Long handle, - @NonNull Result result); - - void referenceUpdateMetadata( - @NonNull PigeonStorageFirebaseApp app, - @NonNull PigeonStorageReference reference, - @NonNull PigeonSettableMetadata metadata, - @NonNull Result result); - - void taskPause( - @NonNull PigeonStorageFirebaseApp app, - @NonNull Long handle, - @NonNull Result> result); - - void taskResume( - @NonNull PigeonStorageFirebaseApp app, - @NonNull Long handle, - @NonNull Result> result); - - void taskCancel( - @NonNull PigeonStorageFirebaseApp app, - @NonNull Long handle, - @NonNull Result> result); - - /** The codec used by FirebaseStorageHostApi. */ - static @NonNull MessageCodec getCodec() { - return FirebaseStorageHostApiCodec.INSTANCE; - } - /** - * Sets up an instance of `FirebaseStorageHostApi` to handle messages through the - * `binaryMessenger`. - */ - static void setup( - @NonNull BinaryMessenger binaryMessenger, @Nullable FirebaseStorageHostApi api) { - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.getReferencebyPath", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - String pathArg = (String) args.get(1); - String bucketArg = (String) args.get(2); - Result resultCallback = - new Result() { - public void success(PigeonStorageReference result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.getReferencebyPath(appArg, pathArg, bucketArg, resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxOperationRetryTime", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - Number timeArg = (Number) args.get(1); - Result resultCallback = - new Result() { - public void success(Void result) { - wrapped.add(0, null); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.setMaxOperationRetryTime( - appArg, (timeArg == null) ? null : timeArg.longValue(), resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxUploadRetryTime", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - Number timeArg = (Number) args.get(1); - Result resultCallback = - new Result() { - public void success(Void result) { - wrapped.add(0, null); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.setMaxUploadRetryTime( - appArg, (timeArg == null) ? null : timeArg.longValue(), resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxDownloadRetryTime", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - Number timeArg = (Number) args.get(1); - Result resultCallback = - new Result() { - public void success(Void result) { - wrapped.add(0, null); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.setMaxDownloadRetryTime( - appArg, (timeArg == null) ? null : timeArg.longValue(), resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.useStorageEmulator", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - String hostArg = (String) args.get(1); - Number portArg = (Number) args.get(2); - Result resultCallback = - new Result() { - public void success(Void result) { - wrapped.add(0, null); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.useStorageEmulator( - appArg, - hostArg, - (portArg == null) ? null : portArg.longValue(), - resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDelete", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - Result resultCallback = - new Result() { - public void success(Void result) { - wrapped.add(0, null); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referenceDelete(appArg, referenceArg, resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetDownloadURL", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - Result resultCallback = - new Result() { - public void success(String result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referenceGetDownloadURL(appArg, referenceArg, resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetMetaData", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - Result resultCallback = - new Result() { - public void success(PigeonFullMetaData result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referenceGetMetaData(appArg, referenceArg, resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceList", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - PigeonListOptions optionsArg = (PigeonListOptions) args.get(2); - Result resultCallback = - new Result() { - public void success(PigeonListResult result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referenceList(appArg, referenceArg, optionsArg, resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceListAll", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - Result resultCallback = - new Result() { - public void success(PigeonListResult result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referenceListAll(appArg, referenceArg, resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetData", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - Number maxSizeArg = (Number) args.get(2); - Result resultCallback = - new Result() { - public void success(byte[] result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referenceGetData( - appArg, - referenceArg, - (maxSizeArg == null) ? null : maxSizeArg.longValue(), - resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutData", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - byte[] dataArg = (byte[]) args.get(2); - PigeonSettableMetadata settableMetaDataArg = (PigeonSettableMetadata) args.get(3); - Number handleArg = (Number) args.get(4); - Result resultCallback = - new Result() { - public void success(String result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referencePutData( - appArg, - referenceArg, - dataArg, - settableMetaDataArg, - (handleArg == null) ? null : handleArg.longValue(), - resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutString", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - String dataArg = (String) args.get(2); - Number formatArg = (Number) args.get(3); - PigeonSettableMetadata settableMetaDataArg = (PigeonSettableMetadata) args.get(4); - Number handleArg = (Number) args.get(5); - Result resultCallback = - new Result() { - public void success(String result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referencePutString( - appArg, - referenceArg, - dataArg, - (formatArg == null) ? null : formatArg.longValue(), - settableMetaDataArg, - (handleArg == null) ? null : handleArg.longValue(), - resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutFile", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - String filePathArg = (String) args.get(2); - PigeonSettableMetadata settableMetaDataArg = (PigeonSettableMetadata) args.get(3); - Number handleArg = (Number) args.get(4); - Result resultCallback = - new Result() { - public void success(String result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referencePutFile( - appArg, - referenceArg, - filePathArg, - settableMetaDataArg, - (handleArg == null) ? null : handleArg.longValue(), - resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDownloadFile", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - String filePathArg = (String) args.get(2); - Number handleArg = (Number) args.get(3); - Result resultCallback = - new Result() { - public void success(String result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referenceDownloadFile( - appArg, - referenceArg, - filePathArg, - (handleArg == null) ? null : handleArg.longValue(), - resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceUpdateMetadata", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - PigeonStorageReference referenceArg = (PigeonStorageReference) args.get(1); - PigeonSettableMetadata metadataArg = (PigeonSettableMetadata) args.get(2); - Result resultCallback = - new Result() { - public void success(PigeonFullMetaData result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.referenceUpdateMetadata(appArg, referenceArg, metadataArg, resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskPause", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - Number handleArg = (Number) args.get(1); - Result> resultCallback = - new Result>() { - public void success(Map result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.taskPause( - appArg, (handleArg == null) ? null : handleArg.longValue(), resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskResume", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - Number handleArg = (Number) args.get(1); - Result> resultCallback = - new Result>() { - public void success(Map result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.taskResume( - appArg, (handleArg == null) ? null : handleArg.longValue(), resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - { - BasicMessageChannel channel = - new BasicMessageChannel<>( - binaryMessenger, - "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskCancel", - getCodec()); - if (api != null) { - channel.setMessageHandler( - (message, reply) -> { - ArrayList wrapped = new ArrayList(); - ArrayList args = (ArrayList) message; - PigeonStorageFirebaseApp appArg = (PigeonStorageFirebaseApp) args.get(0); - Number handleArg = (Number) args.get(1); - Result> resultCallback = - new Result>() { - public void success(Map result) { - wrapped.add(0, result); - reply.reply(wrapped); - } - - public void error(Throwable error) { - ArrayList wrappedError = wrapError(error); - reply.reply(wrappedError); - } - }; - - api.taskCancel( - appArg, (handleArg == null) ? null : handleArg.longValue(), resultCallback); - }); - } else { - channel.setMessageHandler(null); - } - } - } - } -} diff --git a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/TaskStateChannelStreamHandler.java b/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/TaskStateChannelStreamHandler.java deleted file mode 100644 index 418245c7e893..000000000000 --- a/packages/firebase_storage/firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/TaskStateChannelStreamHandler.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright 2023, the Chromium project authors. Please see the AUTHORS file - * for details. All rights reserved. Use of this source code is governed by a - * BSD-style license that can be found in the LICENSE file. - */ -package io.flutter.plugins.firebase.storage; - -import androidx.annotation.Nullable; -import com.google.firebase.storage.FirebaseStorage; -import com.google.firebase.storage.StorageException; -import com.google.firebase.storage.StorageTask; -import io.flutter.plugin.common.EventChannel; -import io.flutter.plugin.common.EventChannel.EventSink; -import io.flutter.plugin.common.EventChannel.StreamHandler; -import java.util.HashMap; -import java.util.Map; - -public class TaskStateChannelStreamHandler implements StreamHandler { - private final FlutterFirebaseStorageTask flutterTask; - private final FirebaseStorage androidStorage; - private final StorageTask androidTask; - private final String identifier; - - private final String TASK_STATE_NAME = "taskState"; - private final String TASK_APP_NAME = "appName"; - private final String TASK_SNAPSHOT = "snapshot"; - private final String TASK_ERROR = "error"; - - public TaskStateChannelStreamHandler( - FlutterFirebaseStorageTask flutterTask, - FirebaseStorage androidStorage, - StorageTask androidTask, - String identifier) { - this.flutterTask = flutterTask; - this.androidStorage = androidStorage; - this.androidTask = androidTask; - this.identifier = identifier; - } - - @Override - public void onListen(Object arguments, EventSink events) { - androidTask.addOnProgressListener( - taskSnapshot -> { - if (flutterTask.isDestroyed()) return; - Map event = getTaskEventMap(taskSnapshot, null); - event.put( - TASK_STATE_NAME, - GeneratedAndroidFirebaseStorage.PigeonStorageTaskState.RUNNING.index); - events.success(event); - flutterTask.notifyResumeObjects(); - }); - - androidTask.addOnPausedListener( - taskSnapshot -> { - if (flutterTask.isDestroyed()) return; - Map event = getTaskEventMap(taskSnapshot, null); - event.put( - TASK_STATE_NAME, GeneratedAndroidFirebaseStorage.PigeonStorageTaskState.PAUSED.index); - events.success(event); - flutterTask.notifyPauseObjects(); - }); - - androidTask.addOnSuccessListener( - taskSnapshot -> { - if (flutterTask.isDestroyed()) return; - Map event = getTaskEventMap(taskSnapshot, null); - event.put( - TASK_STATE_NAME, - GeneratedAndroidFirebaseStorage.PigeonStorageTaskState.SUCCESS.index); - events.success(event); - flutterTask.destroy(); - }); - - androidTask.addOnCanceledListener( - () -> { - if (flutterTask.isDestroyed()) return; - Map event = getTaskEventMap(null, null); - event.put( - TASK_STATE_NAME, - // We use "Error" state as we synthetically update snapshot cancel state in cancel() method in Dart - // This is also inline with iOS which doesn't have a cancel state, only failure - GeneratedAndroidFirebaseStorage.PigeonStorageTaskState.ERROR.index); - // We need to pass an exception that the task was canceled like the other platforms - Map syntheticException = new HashMap<>(); - syntheticException.put( - "code", FlutterFirebaseStorageException.getCode(StorageException.ERROR_CANCELED)); - syntheticException.put( - "message", - FlutterFirebaseStorageException.getMessage(StorageException.ERROR_CANCELED)); - event.put(TASK_ERROR, syntheticException); - events.success(event); - flutterTask.notifyCancelObjects(); - flutterTask.destroy(); - }); - - androidTask.addOnFailureListener( - exception -> { - if (flutterTask.isDestroyed()) return; - Map event = getTaskEventMap(null, exception); - event.put( - TASK_STATE_NAME, GeneratedAndroidFirebaseStorage.PigeonStorageTaskState.ERROR.index); - events.success(event); - flutterTask.destroy(); - }); - } - - @Override - public void onCancel(Object arguments) { - if (!androidTask.isCanceled()) androidTask.cancel(); - if (!flutterTask.isDestroyed()) flutterTask.destroy(); - EventChannel eventChannel = FlutterFirebaseStoragePlugin.eventChannels.get(identifier); - - // Remove stream handler and clear the event channel - if (eventChannel != null) { - eventChannel.setStreamHandler(null); - FlutterFirebaseStoragePlugin.eventChannels.remove(identifier); - } - - if (FlutterFirebaseStoragePlugin.streamHandlers.get(identifier) != null) { - FlutterFirebaseStoragePlugin.streamHandlers.remove(identifier); - } - } - - private Map getTaskEventMap( - @Nullable Object snapshot, @Nullable Exception exception) { - Map arguments = new HashMap<>(); - arguments.put(TASK_APP_NAME, androidStorage.getApp().getName()); - if (snapshot != null) { - arguments.put(TASK_SNAPSHOT, FlutterFirebaseStorageTask.parseTaskSnapshot(snapshot)); - } - if (exception != null) { - arguments.put(TASK_ERROR, FlutterFirebaseStoragePlugin.getExceptionDetails(exception)); - } - return arguments; - } -} diff --git a/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseAppRegistrar.kt b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseAppRegistrar.kt new file mode 100644 index 000000000000..424f5d7c8ffb --- /dev/null +++ b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseAppRegistrar.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2019 The Chromium Authors. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +package io.flutter.plugins.firebase.storage + +import androidx.annotation.Keep +import com.google.firebase.components.Component +import com.google.firebase.components.ComponentRegistrar +import com.google.firebase.platforminfo.LibraryVersionComponent + +@Keep +class FlutterFirebaseAppRegistrar : ComponentRegistrar { + override fun getComponents(): List> { + return listOf( + LibraryVersionComponent.create(BuildConfig.LIBRARY_NAME, BuildConfig.LIBRARY_VERSION) + ) + } +} + + diff --git a/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageException.kt b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageException.kt new file mode 100644 index 000000000000..db671035ee96 --- /dev/null +++ b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageException.kt @@ -0,0 +1,70 @@ +/* + * Copyright 2022, the Chromium project authors. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +package io.flutter.plugins.firebase.storage + +import androidx.annotation.Nullable +import com.google.firebase.storage.StorageException + +internal object FlutterFirebaseStorageException { + @JvmStatic + fun parserExceptionToFlutter(@Nullable nativeException: Exception?): FlutterError { + if (nativeException == null) { + return FlutterError( + "UNKNOWN", + "An unknown error occurred", + null + ) + } + + var code = "UNKNOWN" + var message = "An unknown error occurred:" + nativeException.message + var codeNumber: Int + + if (nativeException is StorageException) { + codeNumber = nativeException.errorCode + code = getCode(codeNumber) + message = getMessage(codeNumber) + } + + return FlutterError(code, message, null) + } + + @JvmStatic + fun getCode(codeNumber: Int): String { + return when (codeNumber) { + StorageException.ERROR_OBJECT_NOT_FOUND -> "object-not-found" + StorageException.ERROR_BUCKET_NOT_FOUND -> "bucket-not-found" + StorageException.ERROR_PROJECT_NOT_FOUND -> "project-not-found" + StorageException.ERROR_QUOTA_EXCEEDED -> "quota-exceeded" + StorageException.ERROR_NOT_AUTHENTICATED -> "unauthenticated" + StorageException.ERROR_NOT_AUTHORIZED -> "unauthorized" + StorageException.ERROR_RETRY_LIMIT_EXCEEDED -> "retry-limit-exceeded" + StorageException.ERROR_INVALID_CHECKSUM -> "invalid-checksum" + StorageException.ERROR_CANCELED -> "canceled" + StorageException.ERROR_UNKNOWN -> "unknown" + else -> "unknown" + } + } + + @JvmStatic + fun getMessage(codeNumber: Int): String { + return when (codeNumber) { + StorageException.ERROR_OBJECT_NOT_FOUND -> "No object exists at the desired reference." + StorageException.ERROR_BUCKET_NOT_FOUND -> "No bucket is configured for Firebase Storage." + StorageException.ERROR_PROJECT_NOT_FOUND -> "No project is configured for Firebase Storage." + StorageException.ERROR_QUOTA_EXCEEDED -> "Quota on your Firebase Storage bucket has been exceeded." + StorageException.ERROR_NOT_AUTHENTICATED -> "User is unauthenticated. Authenticate and try again." + StorageException.ERROR_NOT_AUTHORIZED -> "User is not authorized to perform the desired action." + StorageException.ERROR_RETRY_LIMIT_EXCEEDED -> "The maximum time limit on an operation (upload, download, delete, etc.) has been exceeded." + StorageException.ERROR_INVALID_CHECKSUM -> "File on the client does not match the checksum of the file received by the server." + StorageException.ERROR_CANCELED -> "User cancelled the operation." + StorageException.ERROR_UNKNOWN -> "An unknown error occurred" + else -> "An unknown error occurred" + } + } +} + + diff --git a/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseStoragePlugin.kt b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseStoragePlugin.kt new file mode 100644 index 000000000000..7453d5040713 --- /dev/null +++ b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseStoragePlugin.kt @@ -0,0 +1,508 @@ +/* + * Copyright 2025, the Chromium project authors. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +package io.flutter.plugins.firebase.storage + +import android.net.Uri +import android.util.Base64 +import androidx.annotation.NonNull +import androidx.annotation.Nullable +import com.google.android.gms.tasks.Task +import com.google.android.gms.tasks.TaskCompletionSource +import com.google.firebase.FirebaseApp +import com.google.firebase.storage.FirebaseStorage +import com.google.firebase.storage.ListResult +import com.google.firebase.storage.StorageMetadata +import com.google.firebase.storage.StorageReference +import io.flutter.embedding.engine.plugins.FlutterPlugin +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.EventChannel +import io.flutter.plugin.common.EventChannel.StreamHandler +import io.flutter.plugin.common.MethodChannel +import io.flutter.plugins.firebase.core.FlutterFirebasePlugin +import io.flutter.plugins.firebase.core.FlutterFirebasePlugin.cachedThreadPool +import io.flutter.plugins.firebase.core.FlutterFirebasePluginRegistry +import java.io.File +import java.util.Locale +import java.util.UUID + +class FlutterFirebaseStoragePlugin : FlutterFirebasePlugin, FlutterPlugin, FirebaseStorageHostApi { + private var channel: MethodChannel? = null + private var messenger: BinaryMessenger? = null + + override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { + initInstance(binding.binaryMessenger) + } + + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + FlutterFirebaseStorageTask.cancelInProgressTasks() + channel?.setMethodCallHandler(null) + checkNotNull(messenger) + FirebaseStorageHostApi.setUp(messenger!!, null) + channel = null + messenger = null + removeEventListeners() + } + + private fun initInstance(messenger: BinaryMessenger) { + FlutterFirebasePluginRegistry.registerPlugin(STORAGE_METHOD_CHANNEL_NAME, this) + channel = MethodChannel(messenger, STORAGE_METHOD_CHANNEL_NAME) + FirebaseStorageHostApi.setUp(messenger, this) + this.messenger = messenger + } + + private fun registerEventChannel(prefix: String, identifier: String, handler: StreamHandler): String { + val channelName = "$prefix/$identifier" + val channel = EventChannel(messenger, channelName) + channel.setStreamHandler(handler) + eventChannels[identifier] = channel + streamHandlers[identifier] = handler + return identifier + } + + @Synchronized + private fun removeEventListeners() { + val eventChannelKeys: List = ArrayList(eventChannels.keys) + for (identifier in eventChannelKeys) { + val eventChannel = eventChannels[identifier] + eventChannel?.setStreamHandler(null) + eventChannels.remove(identifier) + } + + val streamHandlerKeys: List = ArrayList(streamHandlers.keys) + for (identifier in streamHandlerKeys) { + val streamHandler = streamHandlers[identifier] + if (streamHandler is TaskStateChannelStreamHandler) { + streamHandler.onCancel(null) + } + streamHandlers.remove(identifier) + } + } + + private fun getStorageFromPigeon(app: PigeonStorageFirebaseApp): FirebaseStorage { + val androidApp = FirebaseApp.getInstance(app.appName) + return FirebaseStorage.getInstance(androidApp, "gs://${app.bucket}") + } + + private fun getReferenceFromPigeon( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference + ): StorageReference { + val androidStorage = getStorageFromPigeon(app) + return androidStorage.getReference(reference.fullPath) + } + + private fun convertToPigeonReference(reference: StorageReference): PigeonStorageReference { + return PigeonStorageReference( + bucket = reference.bucket, + fullPath = reference.path, + name = reference.name + ) + } + + private fun convertToPigeonMetaData(storageMetadata: StorageMetadata?): PigeonFullMetaData { + return PigeonFullMetaData(metadata = parseMetadataToMap(storageMetadata)) + } + + private fun convertToPigeonListResult(listResult: ListResult): PigeonListResult { + val items = listResult.items.map { convertToPigeonReference(it) } + val prefixes = listResult.prefixes.map { convertToPigeonReference(it) } + return PigeonListResult(items = items, pageToken = listResult.pageToken, prefixs = prefixes) + } + + private fun getMetaDataFromPigeon(pigeonSettableMetatdata: PigeonSettableMetadata): StorageMetadata { + val builder = StorageMetadata.Builder() + pigeonSettableMetatdata.contentType?.let { builder.setContentType(it) } + pigeonSettableMetatdata.cacheControl?.let { builder.setCacheControl(it) } + pigeonSettableMetatdata.contentDisposition?.let { builder.setContentDisposition(it) } + pigeonSettableMetatdata.contentEncoding?.let { builder.setContentEncoding(it) } + pigeonSettableMetatdata.contentLanguage?.let { builder.setContentLanguage(it) } + pigeonSettableMetatdata.customMetadata?.forEach { (k, v) -> if (k != null && v != null) builder.setCustomMetadata(k, v) } + return builder.build() + } + + private fun stringToByteData(data: String, format: Int): ByteArray? { + return when (format) { + 1 -> Base64.decode(data, Base64.DEFAULT) // base64 + 2 -> Base64.decode(data, Base64.URL_SAFE) // base64Url + else -> null + } + } + + override fun getReferencebyPath( + app: PigeonStorageFirebaseApp, + path: String, + bucket: String?, + callback: (Result) -> Unit + ) { + val androidReference = getStorageFromPigeon(app).getReference(path) + callback(Result.success(convertToPigeonReference(androidReference))) + } + + override fun useStorageEmulator( + app: PigeonStorageFirebaseApp, + host: String, + port: Long, + callback: (Result) -> Unit + ) { + try { + val storage = getStorageFromPigeon(app) + storage.useEmulator(host, port.toInt()) + callback(Result.success(Unit)) + } catch (e: Exception) { + callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(e))) + } + } + + override fun referenceDelete( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + callback: (Result) -> Unit + ) { + val androidReference = getStorageFromPigeon(app).getReference(reference.fullPath) + androidReference.delete().addOnCompleteListener { task -> + if (task.isSuccessful) callback(Result.success(Unit)) + else callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(task.exception))) + } + } + + override fun referenceGetDownloadURL( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + callback: (Result) -> Unit + ) { + val androidReference = getStorageFromPigeon(app).getReference(reference.fullPath) + androidReference.downloadUrl.addOnCompleteListener { task -> + if (task.isSuccessful) callback(Result.success(task.result.toString())) + else callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(task.exception))) + } + } + + override fun referenceGetData( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + maxSize: Long, + callback: (Result) -> Unit + ) { + val androidReference = getStorageFromPigeon(app).getReference(reference.fullPath) + androidReference.getBytes(maxSize).addOnCompleteListener { task -> + if (task.isSuccessful) callback(Result.success(task.result)) + else callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(task.exception))) + } + } + + override fun referenceGetMetaData( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + callback: (Result) -> Unit + ) { + val androidReference = getStorageFromPigeon(app).getReference(reference.fullPath) + androidReference.metadata.addOnCompleteListener { task -> + if (task.isSuccessful) callback(Result.success(convertToPigeonMetaData(task.result))) + else callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(task.exception))) + } + } + + override fun referenceList( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + options: PigeonListOptions, + callback: (Result) -> Unit + ) { + val androidReference = getStorageFromPigeon(app).getReference(reference.fullPath) + val task = if (options.pageToken != null) { + androidReference.list(options.maxResults.toInt(), options.pageToken) + } else { + androidReference.list(options.maxResults.toInt()) + } + task.addOnCompleteListener { t -> + if (t.isSuccessful) callback(Result.success(convertToPigeonListResult(t.result))) + else callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(t.exception))) + } + } + + override fun referenceListAll( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + callback: (Result) -> Unit + ) { + val androidReference = getStorageFromPigeon(app).getReference(reference.fullPath) + androidReference.listAll().addOnCompleteListener { task -> + if (task.isSuccessful) callback(Result.success(convertToPigeonListResult(task.result))) + else callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(task.exception))) + } + } + + override fun referenceUpdateMetadata( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + metadata: PigeonSettableMetadata, + callback: (Result) -> Unit + ) { + val androidReference = getStorageFromPigeon(app).getReference(reference.fullPath) + androidReference.updateMetadata(getMetaDataFromPigeon(metadata)).addOnCompleteListener { task -> + if (task.isSuccessful) callback(Result.success(convertToPigeonMetaData(task.result))) + else callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(task.exception))) + } + } + + override fun referencePutData( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + data: ByteArray, + settableMetaData: PigeonSettableMetadata, + handle: Long, + callback: (Result) -> Unit + ) { + val androidReference = getReferenceFromPigeon(app, reference) + val androidMetaData = getMetaDataFromPigeon(settableMetaData) + val storageTask = FlutterFirebaseStorageTask.uploadBytes(handle.toInt(), androidReference, data, androidMetaData) + try { + val identifier = UUID.randomUUID().toString().lowercase(Locale.US) + val handler = storageTask.startTaskWithMethodChannel(channel!!, identifier) + callback(Result.success(registerEventChannel("$STORAGE_METHOD_CHANNEL_NAME/$STORAGE_TASK_EVENT_NAME", identifier, handler))) + } catch (e: Exception) { + callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(e))) + } + } + + override fun referencePutString( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + data: String, + format: Long, + settableMetaData: PigeonSettableMetadata, + handle: Long, + callback: (Result) -> Unit + ) { + val androidReference = getReferenceFromPigeon(app, reference) + val androidMetaData = getMetaDataFromPigeon(settableMetaData) + val bytes = stringToByteData(data, format.toInt()) + val storageTask = FlutterFirebaseStorageTask.uploadBytes(handle.toInt(), androidReference, bytes!!, androidMetaData) + try { + val identifier = UUID.randomUUID().toString().lowercase(Locale.US) + val handler = storageTask.startTaskWithMethodChannel(channel!!, identifier) + callback(Result.success(registerEventChannel("$STORAGE_METHOD_CHANNEL_NAME/$STORAGE_TASK_EVENT_NAME", identifier, handler))) + } catch (e: Exception) { + callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(e))) + } + } + + override fun referencePutFile( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + filePath: String, + settableMetaData: PigeonSettableMetadata?, + handle: Long, + callback: (Result) -> Unit + ) { + val androidReference = getReferenceFromPigeon(app, reference) + val storageTask = FlutterFirebaseStorageTask.uploadFile( + handle.toInt(), + androidReference, + Uri.fromFile(File(filePath)), + settableMetaData?.let { getMetaDataFromPigeon(it) } + ) + try { + val identifier = UUID.randomUUID().toString().lowercase(Locale.US) + val handler = storageTask.startTaskWithMethodChannel(channel!!, identifier) + callback(Result.success(registerEventChannel("$STORAGE_METHOD_CHANNEL_NAME/$STORAGE_TASK_EVENT_NAME", identifier, handler))) + } catch (e: Exception) { + callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(e))) + } + } + + override fun referenceDownloadFile( + app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference, + filePath: String, + handle: Long, + callback: (Result) -> Unit + ) { + val androidReference = getReferenceFromPigeon(app, reference) + val storageTask = FlutterFirebaseStorageTask.downloadFile(handle.toInt(), androidReference, File(filePath)) + try { + val identifier = UUID.randomUUID().toString().lowercase(Locale.US) + val handler = storageTask.startTaskWithMethodChannel(channel!!, identifier) + callback(Result.success(registerEventChannel("$STORAGE_METHOD_CHANNEL_NAME/$STORAGE_TASK_EVENT_NAME", identifier, handler))) + } catch (e: Exception) { + callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(e))) + } + } + + override fun taskPause( + app: PigeonStorageFirebaseApp, + handle: Long, + callback: (Result>) -> Unit + ) { + val storageTask = FlutterFirebaseStorageTask.getInProgressTaskForHandle(handle.toInt()) + if (storageTask == null) { + val statusMap = HashMap() + statusMap["status"] = false + callback(Result.success(statusMap)) + return + } + try { + var paused = false + if (!storageTask.isPaused()) { + paused = storageTask.pause() + } + val statusMap = HashMap() + statusMap["status"] = paused + if (paused) { + statusMap["snapshot"] = FlutterFirebaseStorageTask.parseTaskSnapshot(storageTask.getSnapshot()) + } + callback(Result.success(statusMap)) + } catch (e: Exception) { + callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(e))) + } + } + + override fun taskResume( + app: PigeonStorageFirebaseApp, + handle: Long, + callback: (Result>) -> Unit + ) { + val storageTask = FlutterFirebaseStorageTask.getInProgressTaskForHandle(handle.toInt()) + if (storageTask == null) { + val statusMap = HashMap() + statusMap["status"] = false + callback(Result.success(statusMap)) + return + } + try { + var resumed = false + if (storageTask.isPaused()) { + resumed = storageTask.resume() + } + val statusMap = HashMap() + statusMap["status"] = resumed + if (resumed) { + statusMap["snapshot"] = FlutterFirebaseStorageTask.parseTaskSnapshot(storageTask.getSnapshot()) + } + callback(Result.success(statusMap)) + } catch (e: Exception) { + callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(e))) + } + } + + override fun taskCancel( + app: PigeonStorageFirebaseApp, + handle: Long, + callback: (Result>) -> Unit + ) { + val storageTask = FlutterFirebaseStorageTask.getInProgressTaskForHandle(handle.toInt()) + if (storageTask == null) { + val statusMap = HashMap() + statusMap["status"] = false + callback(Result.success(statusMap)) + return + } + try { + val canceled = storageTask.cancel() + val statusMap = HashMap() + statusMap["status"] = canceled + if (canceled) { + statusMap["snapshot"] = FlutterFirebaseStorageTask.parseTaskSnapshot(storageTask.getSnapshot()) + } + callback(Result.success(statusMap)) + } catch (e: Exception) { + callback(Result.failure(FlutterFirebaseStorageException.parserExceptionToFlutter(e))) + } + } + + override fun setMaxOperationRetryTime( + app: PigeonStorageFirebaseApp, + time: Long, + callback: (Result) -> Unit + ) { + val storage = getStorageFromPigeon(app) + storage.maxOperationRetryTimeMillis = time + callback(Result.success(Unit)) + } + + override fun setMaxUploadRetryTime( + app: PigeonStorageFirebaseApp, + time: Long, + callback: (Result) -> Unit + ) { + val storage = getStorageFromPigeon(app) + storage.maxUploadRetryTimeMillis = time + callback(Result.success(Unit)) + } + + override fun setMaxDownloadRetryTime( + app: PigeonStorageFirebaseApp, + time: Long, + callback: (Result) -> Unit + ) { + val storage = getStorageFromPigeon(app) + storage.maxDownloadRetryTimeMillis = time + callback(Result.success(Unit)) + } + + override fun getPluginConstantsForFirebaseApp(firebaseApp: FirebaseApp?): Task> { + val taskCompletionSource = TaskCompletionSource>() + cachedThreadPool.execute { + val obj = HashMap() + taskCompletionSource.setResult(obj) + } + return taskCompletionSource.task + } + + override fun didReinitializeFirebaseCore(): Task { + val taskCompletionSource = TaskCompletionSource() + cachedThreadPool.execute { + FlutterFirebaseStorageTask.cancelInProgressTasks() + taskCompletionSource.setResult(null) + removeEventListeners() + } + return taskCompletionSource.task + } + + companion object { + const val STORAGE_METHOD_CHANNEL_NAME = "plugins.flutter.io/firebase_storage" + const val STORAGE_TASK_EVENT_NAME = "taskEvent" + const val DEFAULT_ERROR_CODE = "firebase_storage" + + val eventChannels: MutableMap = HashMap() + val streamHandlers: MutableMap = HashMap() + + fun getExceptionDetails(exception: Exception): Map { + val storageException = FlutterFirebaseStorageException.parserExceptionToFlutter(exception) + val details: MutableMap = HashMap() + details["code"] = storageException.code + details["message"] = storageException.message ?: "" + return details + } + + fun parseMetadataToMap(storageMetadata: StorageMetadata?): Map? { + if (storageMetadata == null) return null + val out: MutableMap = HashMap() + storageMetadata.name?.let { out["name"] = it } + storageMetadata.bucket?.let { out["bucket"] = it } + storageMetadata.generation?.let { out["generation"] = it } + storageMetadata.metadataGeneration?.let { out["metadataGeneration"] = it } + out["fullPath"] = storageMetadata.path + out["size"] = storageMetadata.sizeBytes + out["creationTimeMillis"] = storageMetadata.creationTimeMillis + out["updatedTimeMillis"] = storageMetadata.updatedTimeMillis + storageMetadata.md5Hash?.let { out["md5Hash"] = it } + storageMetadata.cacheControl?.let { out["cacheControl"] = it } + storageMetadata.contentDisposition?.let { out["contentDisposition"] = it } + storageMetadata.contentEncoding?.let { out["contentEncoding"] = it } + storageMetadata.contentLanguage?.let { out["contentLanguage"] = it } + storageMetadata.contentType?.let { out["contentType"] = it } + val customMetadata: MutableMap = HashMap() + for (key in storageMetadata.customMetadataKeys) { + customMetadata[key] = storageMetadata.getCustomMetadata(key) ?: "" + } + out["customMetadata"] = customMetadata + return out + } + } +} + + diff --git a/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageTask.kt b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageTask.kt new file mode 100644 index 000000000000..1727bbde949c --- /dev/null +++ b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/FlutterFirebaseStorageTask.kt @@ -0,0 +1,160 @@ +/* + * Copyright 2022, the Chromium project authors. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ +package io.flutter.plugins.firebase.storage + +import android.net.Uri +import android.util.SparseArray +import androidx.annotation.NonNull +import androidx.annotation.Nullable +import com.google.firebase.storage.FileDownloadTask +import com.google.firebase.storage.StorageMetadata +import com.google.firebase.storage.StorageReference +import com.google.firebase.storage.StorageTask +import com.google.firebase.storage.UploadTask +import io.flutter.plugin.common.MethodChannel +import java.io.File +import java.util.HashMap + +internal class FlutterFirebaseStorageTask private constructor( + private val type: FlutterFirebaseStorageTaskType, + private val handle: Int, + private val reference: StorageReference, + private val bytes: ByteArray?, + private val fileUri: Uri?, + private val metadata: StorageMetadata? +) { + private val pauseSyncObject = Object() + private val resumeSyncObject = Object() + private val cancelSyncObject = Object() + private lateinit var storageTask: StorageTask<*> + private var destroyed: Boolean = false + + init { + synchronized(inProgressTasks) { inProgressTasks.put(handle, this) } + } + + fun startTaskWithMethodChannel(@NonNull channel: MethodChannel, @NonNull identifier: String): TaskStateChannelStreamHandler { + storageTask = when (type) { + FlutterFirebaseStorageTaskType.BYTES -> if (metadata == null) reference.putBytes(bytes!!) else reference.putBytes(bytes!!, metadata) + FlutterFirebaseStorageTaskType.FILE -> if (metadata == null) reference.putFile(fileUri!!) else reference.putFile(fileUri!!, metadata) + FlutterFirebaseStorageTaskType.DOWNLOAD -> reference.getFile(fileUri!!) + } + + return TaskStateChannelStreamHandler(this, reference.storage, storageTask as Any, identifier) + } + + fun getSnapshot(): Any = storageTask.snapshot + + fun pause(): Boolean = storageTask.pause() + + fun resume(): Boolean = storageTask.resume() + + fun cancel(): Boolean = storageTask.cancel() + + fun isCanceled(): Boolean = storageTask.isCanceled + + fun isInProgress(): Boolean = storageTask.isInProgress + + fun isPaused(): Boolean = storageTask.isPaused + + fun isDestroyed(): Boolean = destroyed + + fun notifyResumeObjects() { synchronized(resumeSyncObject) { resumeSyncObject.notifyAll() } } + fun notifyCancelObjects() { synchronized(cancelSyncObject) { cancelSyncObject.notifyAll() } } + fun notifyPauseObjects() { synchronized(pauseSyncObject) { pauseSyncObject.notifyAll() } } + + // Intentionally do not expose the StorageTask generic type outside this class + + fun destroy() { + if (destroyed) return + destroyed = true + + synchronized(inProgressTasks) { + if (storageTask.isInProgress || storageTask.isPaused) { + storageTask.cancel() + } + inProgressTasks.remove(handle) + } + + synchronized(cancelSyncObject) { cancelSyncObject.notifyAll() } + synchronized(pauseSyncObject) { pauseSyncObject.notifyAll() } + synchronized(resumeSyncObject) { resumeSyncObject.notifyAll() } + } + + companion object { + val inProgressTasks: SparseArray = SparseArray() + + @JvmStatic + fun getInProgressTaskForHandle(handle: Int): FlutterFirebaseStorageTask? { + synchronized(inProgressTasks) { return inProgressTasks.get(handle) } + } + + @JvmStatic + fun cancelInProgressTasks() { + synchronized(inProgressTasks) { + for (i in 0 until inProgressTasks.size()) { + val task: FlutterFirebaseStorageTask? = inProgressTasks.valueAt(i) + task?.destroy() + } + inProgressTasks.clear() + } + } + + @JvmStatic + fun uploadBytes(handle: Int, reference: StorageReference, data: ByteArray, metadata: StorageMetadata?): FlutterFirebaseStorageTask { + return FlutterFirebaseStorageTask(FlutterFirebaseStorageTaskType.BYTES, handle, reference, data, null, metadata) + } + + @JvmStatic + fun uploadFile(handle: Int, reference: StorageReference, fileUri: Uri, metadata: StorageMetadata?): FlutterFirebaseStorageTask { + return FlutterFirebaseStorageTask(FlutterFirebaseStorageTaskType.FILE, handle, reference, null, fileUri, metadata) + } + + @JvmStatic + fun downloadFile(handle: Int, reference: StorageReference, file: File): FlutterFirebaseStorageTask { + return FlutterFirebaseStorageTask(FlutterFirebaseStorageTaskType.DOWNLOAD, handle, reference, null, Uri.fromFile(file), null) + } + + @JvmStatic + fun parseUploadTaskSnapshot(snapshot: UploadTask.TaskSnapshot): Map { + val out: MutableMap = HashMap() + out["path"] = snapshot.storage.path + out["bytesTransferred"] = snapshot.bytesTransferred + out["totalBytes"] = snapshot.totalByteCount + if (snapshot.metadata != null) { + out["metadata"] = FlutterFirebaseStoragePlugin.parseMetadataToMap(snapshot.metadata!!) + } + return out + } + + @JvmStatic + fun parseDownloadTaskSnapshot(snapshot: FileDownloadTask.TaskSnapshot): Map { + val out: MutableMap = HashMap() + out["path"] = snapshot.storage.path + // Workaround: sometimes getBytesTransferred != getTotalByteCount when completed + out["bytesTransferred"] = if (snapshot.task.isSuccessful) snapshot.totalByteCount else snapshot.bytesTransferred + out["totalBytes"] = snapshot.totalByteCount + return out + } + + @JvmStatic + fun parseTaskSnapshot(snapshot: Any): Map { + return if (snapshot is FileDownloadTask.TaskSnapshot) { + parseDownloadTaskSnapshot(snapshot) + } else { + parseUploadTaskSnapshot(snapshot as UploadTask.TaskSnapshot) + } + } + } + + private enum class FlutterFirebaseStorageTaskType { + FILE, + BYTES, + DOWNLOAD + } +} + + diff --git a/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/GeneratedAndroidFirebaseStorage.g.kt b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/GeneratedAndroidFirebaseStorage.g.kt new file mode 100644 index 000000000000..66149daa3d82 --- /dev/null +++ b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/GeneratedAndroidFirebaseStorage.g.kt @@ -0,0 +1,769 @@ +// Copyright 2023, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Autogenerated from Pigeon (v11.0.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +package io.flutter.plugins.firebase.storage + +import android.util.Log +import io.flutter.plugin.common.BasicMessageChannel +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.MessageCodec +import io.flutter.plugin.common.StandardMessageCodec +import java.io.ByteArrayOutputStream +import java.nio.ByteBuffer + +private fun wrapResult(result: Any?): List { + return listOf(result) +} + +private fun wrapError(exception: Throwable): List { + if (exception is FlutterError) { + return listOf( + exception.code, + exception.message, + exception.details + ) + } else { + return listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) + ) + } +} + +/** + * Error class for passing custom error details to Flutter via a thrown PlatformException. + * @property code The error code. + * @property message The error message. + * @property details The error details. Must be a datatype supported by the api codec. + */ +class FlutterError ( + val code: String, + override val message: String? = null, + val details: Any? = null +) : Throwable() + +/** + * The type of operation that generated the action code from calling + * [TaskState]. + */ +enum class PigeonStorageTaskState(val raw: Int) { + /** Indicates the task has been paused by the user. */ + PAUSED(0), + /** Indicates the task is currently in-progress. */ + RUNNING(1), + /** Indicates the task has successfully completed. */ + SUCCESS(2), + /** Indicates the task was canceled. */ + CANCELED(3), + /** Indicates the task failed with an error. */ + ERROR(4); + + companion object { + fun ofRaw(raw: Int): PigeonStorageTaskState? { + return values().firstOrNull { it.raw == raw } + } + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class PigeonStorageFirebaseApp ( + val appName: String, + val tenantId: String? = null, + val bucket: String + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): PigeonStorageFirebaseApp { + val appName = list[0] as String + val tenantId = list[1] as String? + val bucket = list[2] as String + return PigeonStorageFirebaseApp(appName, tenantId, bucket) + } + } + fun toList(): List { + return listOf( + appName, + tenantId, + bucket, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class PigeonStorageReference ( + val bucket: String, + val fullPath: String, + val name: String + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): PigeonStorageReference { + val bucket = list[0] as String + val fullPath = list[1] as String + val name = list[2] as String + return PigeonStorageReference(bucket, fullPath, name) + } + } + fun toList(): List { + return listOf( + bucket, + fullPath, + name, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class PigeonFullMetaData ( + val metadata: Map? = null + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): PigeonFullMetaData { + val metadata = list[0] as Map? + return PigeonFullMetaData(metadata) + } + } + fun toList(): List { + return listOf( + metadata, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class PigeonListOptions ( + /** + * If set, limits the total number of `prefixes` and `items` to return. + * + * The default and maximum maxResults is 1000. + */ + val maxResults: Long, + /** + * The nextPageToken from a previous call to list(). + * + * If provided, listing is resumed from the previous position. + */ + val pageToken: String? = null + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): PigeonListOptions { + val maxResults = list[0].let { if (it is Int) it.toLong() else it as Long } + val pageToken = list[1] as String? + return PigeonListOptions(maxResults, pageToken) + } + } + fun toList(): List { + return listOf( + maxResults, + pageToken, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class PigeonSettableMetadata ( + /** + * Served as the 'Cache-Control' header on object download. + * + * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control. + */ + val cacheControl: String? = null, + /** + * Served as the 'Content-Disposition' header on object download. + * + * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition. + */ + val contentDisposition: String? = null, + /** + * Served as the 'Content-Encoding' header on object download. + * + * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding. + */ + val contentEncoding: String? = null, + /** + * Served as the 'Content-Language' header on object download. + * + * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language. + */ + val contentLanguage: String? = null, + /** + * Served as the 'Content-Type' header on object download. + * + * See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type. + */ + val contentType: String? = null, + /** Additional user-defined custom metadata. */ + val customMetadata: Map? = null + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): PigeonSettableMetadata { + val cacheControl = list[0] as String? + val contentDisposition = list[1] as String? + val contentEncoding = list[2] as String? + val contentLanguage = list[3] as String? + val contentType = list[4] as String? + val customMetadata = list[5] as Map? + return PigeonSettableMetadata(cacheControl, contentDisposition, contentEncoding, contentLanguage, contentType, customMetadata) + } + } + fun toList(): List { + return listOf( + cacheControl, + contentDisposition, + contentEncoding, + contentLanguage, + contentType, + customMetadata, + ) + } +} + +/** Generated class from Pigeon that represents data sent in messages. */ +data class PigeonListResult ( + val items: List, + val pageToken: String? = null, + val prefixs: List + +) { + companion object { + @Suppress("UNCHECKED_CAST") + fun fromList(list: List): PigeonListResult { + val items = list[0] as List + val pageToken = list[1] as String? + val prefixs = list[2] as List + return PigeonListResult(items, pageToken, prefixs) + } + } + fun toList(): List { + return listOf( + items, + pageToken, + prefixs, + ) + } +} + +@Suppress("UNCHECKED_CAST") +private object FirebaseStorageHostApiCodec : StandardMessageCodec() { + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return when (type) { + 128.toByte() -> { + return (readValue(buffer) as? List)?.let { + PigeonFullMetaData.fromList(it) + } + } + 129.toByte() -> { + return (readValue(buffer) as? List)?.let { + PigeonListOptions.fromList(it) + } + } + 130.toByte() -> { + return (readValue(buffer) as? List)?.let { + PigeonListResult.fromList(it) + } + } + 131.toByte() -> { + return (readValue(buffer) as? List)?.let { + PigeonSettableMetadata.fromList(it) + } + } + 132.toByte() -> { + return (readValue(buffer) as? List)?.let { + PigeonStorageFirebaseApp.fromList(it) + } + } + 133.toByte() -> { + return (readValue(buffer) as? List)?.let { + PigeonStorageReference.fromList(it) + } + } + else -> super.readValueOfType(type, buffer) + } + } + override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { + when (value) { + is PigeonFullMetaData -> { + stream.write(128) + writeValue(stream, value.toList()) + } + is PigeonListOptions -> { + stream.write(129) + writeValue(stream, value.toList()) + } + is PigeonListResult -> { + stream.write(130) + writeValue(stream, value.toList()) + } + is PigeonSettableMetadata -> { + stream.write(131) + writeValue(stream, value.toList()) + } + is PigeonStorageFirebaseApp -> { + stream.write(132) + writeValue(stream, value.toList()) + } + is PigeonStorageReference -> { + stream.write(133) + writeValue(stream, value.toList()) + } + else -> super.writeValue(stream, value) + } + } +} + +/** Generated interface from Pigeon that represents a handler of messages from Flutter. */ +interface FirebaseStorageHostApi { + fun getReferencebyPath(app: PigeonStorageFirebaseApp, path: String, bucket: String?, callback: (Result) -> Unit) + fun setMaxOperationRetryTime(app: PigeonStorageFirebaseApp, time: Long, callback: (Result) -> Unit) + fun setMaxUploadRetryTime(app: PigeonStorageFirebaseApp, time: Long, callback: (Result) -> Unit) + fun setMaxDownloadRetryTime(app: PigeonStorageFirebaseApp, time: Long, callback: (Result) -> Unit) + fun useStorageEmulator(app: PigeonStorageFirebaseApp, host: String, port: Long, callback: (Result) -> Unit) + fun referenceDelete(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, callback: (Result) -> Unit) + fun referenceGetDownloadURL(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, callback: (Result) -> Unit) + fun referenceGetMetaData(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, callback: (Result) -> Unit) + fun referenceList(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, options: PigeonListOptions, callback: (Result) -> Unit) + fun referenceListAll(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, callback: (Result) -> Unit) + fun referenceGetData(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, maxSize: Long, callback: (Result) -> Unit) + fun referencePutData(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, data: ByteArray, settableMetaData: PigeonSettableMetadata, handle: Long, callback: (Result) -> Unit) + fun referencePutString(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, data: String, format: Long, settableMetaData: PigeonSettableMetadata, handle: Long, callback: (Result) -> Unit) + fun referencePutFile(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, filePath: String, settableMetaData: PigeonSettableMetadata?, handle: Long, callback: (Result) -> Unit) + fun referenceDownloadFile(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, filePath: String, handle: Long, callback: (Result) -> Unit) + fun referenceUpdateMetadata(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, metadata: PigeonSettableMetadata, callback: (Result) -> Unit) + fun taskPause(app: PigeonStorageFirebaseApp, handle: Long, callback: (Result>) -> Unit) + fun taskResume(app: PigeonStorageFirebaseApp, handle: Long, callback: (Result>) -> Unit) + fun taskCancel(app: PigeonStorageFirebaseApp, handle: Long, callback: (Result>) -> Unit) + + companion object { + /** The codec used by FirebaseStorageHostApi. */ + val codec: MessageCodec by lazy { + FirebaseStorageHostApiCodec + } + /** Sets up an instance of `FirebaseStorageHostApi` to handle messages through the `binaryMessenger`. */ + @Suppress("UNCHECKED_CAST") + fun setUp(binaryMessenger: BinaryMessenger, api: FirebaseStorageHostApi?) { + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.getReferencebyPath", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val pathArg = args[1] as String + val bucketArg = args[2] as String? + api.getReferencebyPath(appArg, pathArg, bucketArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxOperationRetryTime", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val timeArg = args[1].let { if (it is Int) it.toLong() else it as Long } + api.setMaxOperationRetryTime(appArg, timeArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxUploadRetryTime", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val timeArg = args[1].let { if (it is Int) it.toLong() else it as Long } + api.setMaxUploadRetryTime(appArg, timeArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxDownloadRetryTime", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val timeArg = args[1].let { if (it is Int) it.toLong() else it as Long } + api.setMaxDownloadRetryTime(appArg, timeArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.useStorageEmulator", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val hostArg = args[1] as String + val portArg = args[2].let { if (it is Int) it.toLong() else it as Long } + api.useStorageEmulator(appArg, hostArg, portArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDelete", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + api.referenceDelete(appArg, referenceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetDownloadURL", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + api.referenceGetDownloadURL(appArg, referenceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetMetaData", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + api.referenceGetMetaData(appArg, referenceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceList", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + val optionsArg = args[2] as PigeonListOptions + api.referenceList(appArg, referenceArg, optionsArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceListAll", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + api.referenceListAll(appArg, referenceArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetData", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + val maxSizeArg = args[2].let { if (it is Int) it.toLong() else it as Long } + api.referenceGetData(appArg, referenceArg, maxSizeArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutData", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + val dataArg = args[2] as ByteArray + val settableMetaDataArg = args[3] as PigeonSettableMetadata + val handleArg = args[4].let { if (it is Int) it.toLong() else it as Long } + api.referencePutData(appArg, referenceArg, dataArg, settableMetaDataArg, handleArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutString", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + val dataArg = args[2] as String + val formatArg = args[3].let { if (it is Int) it.toLong() else it as Long } + val settableMetaDataArg = args[4] as PigeonSettableMetadata + val handleArg = args[5].let { if (it is Int) it.toLong() else it as Long } + api.referencePutString(appArg, referenceArg, dataArg, formatArg, settableMetaDataArg, handleArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutFile", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + val filePathArg = args[2] as String + val settableMetaDataArg = args[3] as PigeonSettableMetadata? + val handleArg = args[4].let { if (it is Int) it.toLong() else it as Long } + api.referencePutFile(appArg, referenceArg, filePathArg, settableMetaDataArg, handleArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDownloadFile", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + val filePathArg = args[2] as String + val handleArg = args[3].let { if (it is Int) it.toLong() else it as Long } + api.referenceDownloadFile(appArg, referenceArg, filePathArg, handleArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceUpdateMetadata", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val referenceArg = args[1] as PigeonStorageReference + val metadataArg = args[2] as PigeonSettableMetadata + api.referenceUpdateMetadata(appArg, referenceArg, metadataArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskPause", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val handleArg = args[1].let { if (it is Int) it.toLong() else it as Long } + api.taskPause(appArg, handleArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskResume", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val handleArg = args[1].let { if (it is Int) it.toLong() else it as Long } + api.taskResume(appArg, handleArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskCancel", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val appArg = args[0] as PigeonStorageFirebaseApp + val handleArg = args[1].let { if (it is Int) it.toLong() else it as Long } + api.taskCancel(appArg, handleArg) { result: Result> -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } + } + } +} diff --git a/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/TaskStateChannelStreamHandler.kt b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/TaskStateChannelStreamHandler.kt new file mode 100644 index 000000000000..06cc7eddaadb --- /dev/null +++ b/packages/firebase_storage/firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/TaskStateChannelStreamHandler.kt @@ -0,0 +1,103 @@ +/* + * Copyright 2023, the Chromium project authors. + * Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + */ +package io.flutter.plugins.firebase.storage + +import androidx.annotation.Nullable +import com.google.firebase.storage.FirebaseStorage +import com.google.firebase.storage.StorageException +import com.google.firebase.storage.StorageTask +import io.flutter.plugin.common.EventChannel +import io.flutter.plugin.common.EventChannel.EventSink +import io.flutter.plugin.common.EventChannel.StreamHandler +import java.util.HashMap + +internal class TaskStateChannelStreamHandler( + private val flutterTask: FlutterFirebaseStorageTask, + private val androidStorage: FirebaseStorage, + task: Any, + private val identifier: String +) : StreamHandler { + + private val androidTask: StorageTask<*> = task as StorageTask<*> + + private val TASK_STATE_NAME = "taskState" + private val TASK_APP_NAME = "appName" + private val TASK_SNAPSHOT = "snapshot" + private val TASK_ERROR = "error" + + override fun onListen(arguments: Any?, events: EventSink) { + androidTask.addOnProgressListener { taskSnapshot -> + if (flutterTask.isDestroyed()) return@addOnProgressListener + val event = getTaskEventMap(taskSnapshot, null) + event[TASK_STATE_NAME] = PigeonStorageTaskState.RUNNING.raw + events.success(event) + flutterTask.notifyResumeObjects() + } + + androidTask.addOnPausedListener { taskSnapshot -> + if (flutterTask.isDestroyed()) return@addOnPausedListener + val event = getTaskEventMap(taskSnapshot, null) + event[TASK_STATE_NAME] = PigeonStorageTaskState.PAUSED.raw + events.success(event) + flutterTask.notifyPauseObjects() + } + + androidTask.addOnSuccessListener { taskSnapshot -> + if (flutterTask.isDestroyed()) return@addOnSuccessListener + val event = getTaskEventMap(taskSnapshot, null) + event[TASK_STATE_NAME] = PigeonStorageTaskState.SUCCESS.raw + events.success(event) + flutterTask.destroy() + } + + androidTask.addOnCanceledListener { + if (flutterTask.isDestroyed()) return@addOnCanceledListener + val event = getTaskEventMap(null, null) + event[TASK_STATE_NAME] = PigeonStorageTaskState.ERROR.raw + val syntheticException: MutableMap = HashMap() + syntheticException["code"] = FlutterFirebaseStorageException.getCode(StorageException.ERROR_CANCELED) + syntheticException["message"] = FlutterFirebaseStorageException.getMessage(StorageException.ERROR_CANCELED) + event[TASK_ERROR] = syntheticException + events.success(event) + flutterTask.notifyCancelObjects() + flutterTask.destroy() + } + + androidTask.addOnFailureListener { exception -> + if (flutterTask.isDestroyed()) return@addOnFailureListener + val event = getTaskEventMap(null, exception) + event[TASK_STATE_NAME] = PigeonStorageTaskState.ERROR.raw + events.success(event) + flutterTask.destroy() + } + } + + override fun onCancel(arguments: Any?) { + if (!androidTask.isCanceled) androidTask.cancel() + if (!flutterTask.isDestroyed()) flutterTask.destroy() + val eventChannel = FlutterFirebaseStoragePlugin.eventChannels[identifier] + if (eventChannel != null) { + eventChannel.setStreamHandler(null) + FlutterFirebaseStoragePlugin.eventChannels.remove(identifier) + } + if (FlutterFirebaseStoragePlugin.streamHandlers[identifier] != null) { + FlutterFirebaseStoragePlugin.streamHandlers.remove(identifier) + } + } + + private fun getTaskEventMap(@Nullable snapshot: Any?, @Nullable exception: Exception?): MutableMap { + val arguments: MutableMap = HashMap() + arguments[TASK_APP_NAME] = androidStorage.app.name + if (snapshot != null) { + arguments[TASK_SNAPSHOT] = FlutterFirebaseStorageTask.parseTaskSnapshot(snapshot) + } + if (exception != null) { + arguments[TASK_ERROR] = FlutterFirebaseStoragePlugin.getExceptionDetails(exception) + } + return arguments + } +} + + diff --git a/packages/firebase_storage/firebase_storage/ios/firebase_storage.podspec b/packages/firebase_storage/firebase_storage/ios/firebase_storage.podspec index a6a75ac99b4b..7a475510a123 100755 --- a/packages/firebase_storage/firebase_storage/ios/firebase_storage.podspec +++ b/packages/firebase_storage/firebase_storage/ios/firebase_storage.podspec @@ -25,9 +25,11 @@ Pod::Spec.new do |s| s.authors = 'The Chromium Authors' s.source = { :path => '.' } - s.source_files = 'firebase_storage/Sources/firebase_storage/**/*.{h,m}' + s.source_files = 'firebase_storage/Sources/firebase_storage/**/*.{h,m,swift}' s.public_header_files = 'firebase_storage/Sources/firebase_storage/include/*.h' + s.swift_version = '5.0' + s.ios.deployment_target = '15.0' s.dependency 'Flutter' diff --git a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.m b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.m deleted file mode 100644 index 24e972453487..000000000000 --- a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.m +++ /dev/null @@ -1,986 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -#import - -@import FirebaseStorage; -#if __has_include() -#import -#else -#import -#endif -#import "FLTFirebaseStoragePlugin.h" -#import "FLTTaskStateChannelStreamHandler.h" - -static NSString *const kFLTFirebaseStorageChannelName = @"plugins.flutter.io/firebase_storage"; -static NSString *const kFLTFirebaseStorageKeyCacheControl = @"cacheControl"; -static NSString *const kFLTFirebaseStorageKeyContentDisposition = @"contentDisposition"; -static NSString *const kFLTFirebaseStorageKeyContentEncoding = @"contentEncoding"; -static NSString *const kFLTFirebaseStorageKeyContentLanguage = @"contentLanguage"; -static NSString *const kFLTFirebaseStorageKeyContentType = @"contentType"; -static NSString *const kFLTFirebaseStorageKeyCustomMetadata = @"customMetadata"; -static NSString *const kFLTFirebaseStorageKeyName = @"name"; -static NSString *const kFLTFirebaseStorageKeyBucket = @"bucket"; -static NSString *const kFLTFirebaseStorageKeyGeneration = @"generation"; -static NSString *const kFLTFirebaseStorageKeyMetadataGeneration = @"metadataGeneration"; -static NSString *const kFLTFirebaseStorageKeyFullPath = @"fullPath"; -static NSString *const kFLTFirebaseStorageKeySize = @"size"; -static NSString *const kFLTFirebaseStorageKeyCreationTime = @"creationTimeMillis"; -static NSString *const kFLTFirebaseStorageKeyUpdatedTime = @"updatedTimeMillis"; -static NSString *const kFLTFirebaseStorageKeyMD5Hash = @"md5Hash"; -static NSString *const kFLTFirebaseStorageKeyAppName = @"appName"; -static NSString *const kFLTFirebaseStorageKeyMaxOperationRetryTime = @"maxOperationRetryTime"; -static NSString *const kFLTFirebaseStorageKeyMaxDownloadRetryTime = @"maxDownloadRetryTime"; -static NSString *const kFLTFirebaseStorageKeyMaxUploadRetryTime = @"maxUploadRetryTime"; -static NSString *const kFLTFirebaseStorageKeyPath = @"path"; -static NSString *const kFLTFirebaseStorageKeySnapshot = @"snapshot"; -static NSString *const kFLTFirebaseStorageKeyHandle = @"handle"; -static NSString *const kFLTFirebaseStorageKeyMetadata = @"metadata"; -static NSString *const kFLTFirebaseStorageKeyPageToken = @"pageToken"; -static NSString *const kFLTFirebaseStorageKeyOptions = @"options"; -static NSString *const kFLTFirebaseStorageKeyMaxResults = @"maxResults"; -static NSString *const kFLTFirebaseStorageKeyItems = @"items"; -static NSString *const kFLTFirebaseStorageKeyPrefixes = @"prefixes"; -static NSString *const kFLTFirebaseStorageKeyNextPageToken = @"nextPageToken"; -static NSString *const kFLTFirebaseStorageKeyMaxSize = @"maxSize"; - -typedef NS_ENUM(NSUInteger, FLTFirebaseStorageTaskState) { - FLTFirebaseStorageTaskStateCancel = 0, - FLTFirebaseStorageTaskStatePause = 1, - FLTFirebaseStorageTaskStateResume = 2, -}; - -typedef NS_ENUM(NSUInteger, FLTFirebaseStorageTaskType) { - FLTFirebaseStorageTaskTypeFile = 0, - FLTFirebaseStorageTaskTypeBytes = 1, - FLTFirebaseStorageTaskTypeDownload = 2, - FLTFirebaseStorageTaskTypeString = 3, -}; - -typedef NS_ENUM(NSUInteger, FLTFirebaseStorageStringType) { - // FLTFirebaseStorageStringTypeRaw = 0, // unused - FLTFirebaseStorageStringTypeBase64 = 1, - FLTFirebaseStorageStringTypeBase64URL = 2, - // FLTFirebaseStorageStringTypeDataUrl = 3, // unused -}; - -@interface FLTFirebaseStoragePlugin () -@property(nonatomic, retain) FlutterMethodChannel *storage_method_channel; - -@end - -@implementation FLTFirebaseStoragePlugin { - NSMutableDictionary *> *_tasks; - dispatch_queue_t _callbackQueue; - NSMutableDictionary *_emulatorBooted; - NSObject *_binaryMessenger; - NSMutableDictionary *_eventChannels; - NSMutableDictionary *> *_streamHandlers; -} - -#pragma mark - FlutterPlugin - -// Returns a singleton instance of the Firebase Storage plugin. -+ (instancetype)sharedInstance:(NSObject *)messenger { - static dispatch_once_t onceToken; - static FLTFirebaseStoragePlugin *instance; - - dispatch_once(&onceToken, ^{ - instance = [[FLTFirebaseStoragePlugin alloc] init:messenger]; - // Register with the Flutter Firebase plugin registry. - [[FLTFirebasePluginRegistry sharedInstance] registerFirebasePlugin:instance]; - }); - - return instance; -} - -- (instancetype)init:(NSObject *)messenger { - self = [super init]; - if (self) { - _tasks = [NSMutableDictionary *> - dictionary]; - _callbackQueue = - dispatch_queue_create("io.flutter.plugins.firebase.storage", DISPATCH_QUEUE_SERIAL); - _emulatorBooted = [[NSMutableDictionary alloc] init]; - _binaryMessenger = messenger; - _eventChannels = [NSMutableDictionary dictionary]; - _streamHandlers = [NSMutableDictionary dictionary]; - } - return self; -} - -+ (void)registerWithRegistrar:(NSObject *)registrar { - FlutterMethodChannel *channel = - [FlutterMethodChannel methodChannelWithName:kFLTFirebaseStorageChannelName - binaryMessenger:[registrar messenger]]; - - FLTFirebaseStoragePlugin *instance = - [FLTFirebaseStoragePlugin sharedInstance:[registrar messenger]]; - if (instance.storage_method_channel != nil) { - NSLog(@"FLTFirebaseStorage was already registered. If using isolates, you can safely ignore " - @"this message."); - return; - } - instance.storage_method_channel = channel; -#if TARGET_OS_OSX - // TODO(Salakar): Publish does not exist on MacOS version of FlutterPluginRegistrar. -#else - [registrar publish:instance]; -#endif - [registrar addMethodCallDelegate:instance channel:channel]; - - FirebaseStorageHostApiSetup(registrar.messenger, instance); -} - -- (void)cleanupWithCompletion:(void (^)(void))completion { - for (FlutterEventChannel *channel in self->_eventChannels.allValues) { - [channel setStreamHandler:nil]; - } - [self->_eventChannels removeAllObjects]; - for (NSObject *handler in self->_streamHandlers.allValues) { - [handler onCancelWithArguments:nil]; - } - [self->_streamHandlers removeAllObjects]; - @synchronized(self->_tasks) { - for (NSNumber *key in [self->_tasks allKeys]) { - FIRStorageObservableTask *task = self->_tasks[key]; - if (task != nil) { - [task removeAllObservers]; - [task cancel]; - } - } - [self->_tasks removeAllObjects]; - if (completion != nil) completion(); - } -} - -- (void)detachFromEngineForRegistrar:(NSObject *)registrar { - [self cleanupWithCompletion:^() { - self.storage_method_channel = nil; - }]; -} - -- (FIRStorage *_Nullable)getFIRStorageFromAppNameFromPigeon:(PigeonStorageFirebaseApp *)pigeonApp { - FIRApp *app = [FLTFirebasePlugin firebaseAppNamed:pigeonApp.appName]; - NSString *baseString = @"gs://"; - NSString *fullURL = [baseString stringByAppendingString:pigeonApp.bucket]; - - FIRStorage *storage = [FIRStorage storageForApp:app URL:fullURL]; - - return storage; -} - -- (FIRStorageReference *_Nullable) - getFIRStorageReferenceFromPigeon:(PigeonStorageFirebaseApp *)pigeonApp - reference:(PigeonStorageReference *)reference { - FIRStorage *storage = [self getFIRStorageFromAppNameFromPigeon:pigeonApp]; - return [storage referenceWithPath:reference.fullPath]; -} - -- (FIRStorageMetadata *)getFIRStorageMetadataFromPigeon:(PigeonSettableMetadata *)pigeonMetadata { - FIRStorageMetadata *metadata = [[FIRStorageMetadata alloc] init]; - - if (pigeonMetadata.cacheControl != nil) { - metadata.cacheControl = pigeonMetadata.cacheControl; - } - if (pigeonMetadata.contentType != nil) { - metadata.contentType = pigeonMetadata.contentType; - } - if (pigeonMetadata.contentDisposition != nil) { - metadata.contentDisposition = pigeonMetadata.contentDisposition; - } - - if (pigeonMetadata.contentEncoding != nil) { - metadata.contentEncoding = pigeonMetadata.contentEncoding; - } - - if (pigeonMetadata.contentLanguage != nil) { - metadata.contentLanguage = pigeonMetadata.contentLanguage; - } - - if (pigeonMetadata.customMetadata != nil) { - metadata.customMetadata = pigeonMetadata.customMetadata; - } - - return metadata; -} - -- (PigeonStorageReference *)makePigeonStorageReference:(FIRStorageReference *)reference { - return [PigeonStorageReference makeWithBucket:reference.bucket - fullPath:reference.fullPath - name:reference.name]; -} - -#pragma mark - Firebase Storage API - -- (void)getReferencebyPathApp:(PigeonStorageFirebaseApp *)app - path:(NSString *)path - bucket:(nullable NSString *)bucket - completion:(void (^)(PigeonStorageReference *_Nullable, - FlutterError *_Nullable))completion { - FIRStorage *storage = [self getFIRStorageFromAppNameFromPigeon:app]; - FIRStorageReference *storage_ref = [storage referenceWithPath:path]; - completion([PigeonStorageReference makeWithBucket:bucket - fullPath:storage_ref.fullPath - name:storage_ref.name], - nil); -} - -- (void)setMaxOperationRetryTimeApp:(PigeonStorageFirebaseApp *)app - time:(NSNumber *)time - completion:(void (^)(FlutterError *_Nullable))completion { - FIRStorage *storage = [self getFIRStorageFromAppNameFromPigeon:app]; - if (![time isEqual:[NSNull null]]) { - storage.maxOperationRetryTime = [time longLongValue] / 1000.0; - } - completion(nil); -} - -- (void)setMaxUploadRetryTimeApp:(PigeonStorageFirebaseApp *)app - time:(NSNumber *)time - completion:(void (^)(FlutterError *_Nullable))completion { - FIRStorage *storage = [self getFIRStorageFromAppNameFromPigeon:app]; - if (![time isEqual:[NSNull null]]) { - storage.maxUploadRetryTime = [time longLongValue] / 1000.0; - } - completion(nil); -} - -- (void)setMaxDownloadRetryTimeApp:(PigeonStorageFirebaseApp *)app - time:(NSNumber *)time - completion:(void (^)(FlutterError *_Nullable))completion { - FIRStorage *storage = [self getFIRStorageFromAppNameFromPigeon:app]; - if (![time isEqual:[NSNull null]]) { - storage.maxDownloadRetryTime = [time longLongValue] / 1000.0; - } - completion(nil); -} - -- (void)useStorageEmulatorApp:(PigeonStorageFirebaseApp *)app - host:(NSString *)host - port:(NSNumber *)port - completion:(void (^)(FlutterError *_Nullable))completion { - FIRStorage *storage = [self getFIRStorageFromAppNameFromPigeon:app]; - NSNumber *emulatorKey = _emulatorBooted[app.bucket]; - - if (emulatorKey == nil) { - [storage useEmulatorWithHost:host port:[port integerValue]]; - [_emulatorBooted setObject:@(YES) forKey:app.bucket]; - } - completion(nil); -} - -- (void)referenceDeleteApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - completion:(void (^)(FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - [storage_reference deleteWithCompletion:^(NSError *error) { - completion([self FlutterErrorFromNSError:error]); - }]; -} - -- (void)referenceGetDownloadURLApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - completion: - (void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - [storage_reference downloadURLWithCompletion:^(NSURL *URL, NSError *error) { - if (error != nil) { - completion(nil, [self FlutterErrorFromNSError:error]); - } else { - NSString *url = URL.absoluteString; - - if ([url rangeOfString:@":443"].location != NSNotFound) { - NSRange replaceRange = [url rangeOfString:@":443"]; - url = [url stringByReplacingCharactersInRange:replaceRange withString:@""]; - } - - completion(url, nil); - } - }]; -} - -- (void)referenceGetMetaDataApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - completion:(void (^)(PigeonFullMetaData *_Nullable, - FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - - [storage_reference metadataWithCompletion:^(FIRStorageMetadata *metadata, NSError *error) { - if (error != nil) { - completion(nil, [self FlutterErrorFromNSError:error]); - } else { - NSDictionary *dict = [FLTFirebaseStoragePlugin NSDictionaryFromFIRStorageMetadata:metadata]; - completion([PigeonFullMetaData makeWithMetadata:dict], nil); - } - }]; -} - -- (PigeonListResult *)makePigeonListResult:(FIRStorageListResult *)listResult { - NSMutableArray *items = - [NSMutableArray arrayWithCapacity:listResult.items.count]; - for (FIRStorageReference *item in listResult.items) { - [items addObject:[self makePigeonStorageReference:item]]; - } - NSMutableArray *prefixes = - [NSMutableArray arrayWithCapacity:listResult.prefixes.count]; - for (FIRStorageReference *prefix in listResult.prefixes) { - [prefixes addObject:[self makePigeonStorageReference:prefix]]; - } - return [PigeonListResult makeWithItems:items pageToken:listResult.pageToken prefixs:prefixes]; -} - -- (void)referenceListApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - options:(PigeonListOptions *)options - completion: - (void (^)(PigeonListResult *_Nullable, FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - - id result_completion = ^(FIRStorageListResult *listResult, NSError *error) { - if (error != nil) { - completion(nil, [self FlutterErrorFromNSError:error]); - } else { - completion([self makePigeonListResult:listResult], nil); - } - }; - if (options.pageToken == nil) { - [storage_reference listWithMaxResults:options.maxResults.longLongValue - completion:result_completion]; - } else { - [storage_reference listWithMaxResults:options.maxResults.longLongValue - pageToken:options.pageToken - completion:result_completion]; - } -} - -- (void)referenceListAllApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - completion: - (void (^)(PigeonListResult *_Nullable, FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - [storage_reference listAllWithCompletion:^(FIRStorageListResult *listResult, NSError *error) { - if (error != nil) { - completion(nil, [self FlutterErrorFromNSError:error]); - } else { - completion([self makePigeonListResult:listResult], nil); - } - }]; -} - -- (void)referenceGetDataApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - maxSize:(NSNumber *)maxSize - completion:(void (^)(FlutterStandardTypedData *_Nullable, - FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - - [storage_reference - dataWithMaxSize:[maxSize longLongValue] - completion:^(NSData *_Nullable data, NSError *_Nullable error) { - if (error != nil) { - completion(nil, [self FlutterErrorFromNSError:error]); - } else { - FlutterStandardTypedData *typedData; - if (data == nil) { - typedData = [FlutterStandardTypedData typedDataWithBytes:[[NSData alloc] init]]; - } else { - typedData = [FlutterStandardTypedData typedDataWithBytes:data]; - } - completion(typedData, nil); - } - }]; -} - -- (void)referencePutDataApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - data:(FlutterStandardTypedData *)data - settableMetaData:(PigeonSettableMetadata *)settableMetaData - handle:(NSNumber *)handle - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - - FIRStorageMetadata *metadata = [self getFIRStorageMetadataFromPigeon:settableMetaData]; - - FIRStorageObservableTask *task = [storage_reference putData:data.data - metadata:metadata]; - - @synchronized(self->_tasks) { - self->_tasks[handle] = task; - } - - completion([self setupTaskListeners:task handle:handle], nil); -} - -- (NSString *)setupTaskListeners:(FIRStorageObservableTask *)task handle:(NSNumber *)handle { - // Generate a random UUID to register with - NSString *uuid = [[NSUUID UUID] UUIDString]; - - // Set up task listeners - NSString *channelName = - [NSString stringWithFormat:@"%@/taskEvent/%@", kFLTFirebaseStorageChannelName, uuid]; - - FlutterEventChannel *channel = [FlutterEventChannel eventChannelWithName:channelName - binaryMessenger:_binaryMessenger]; - FLTTaskStateChannelStreamHandler *handler = - [[FLTTaskStateChannelStreamHandler alloc] initWithTask:task - storagePlugin:self - channelName:channelName - handle:handle]; - [channel setStreamHandler:handler]; - - [_eventChannels setObject:channel forKey:channelName]; - [_streamHandlers setObject:handler forKey:channelName]; - - return uuid; -} - -- (void)cleanUpTask:(NSString *)channelName handle:(NSNumber *)handle { - NSObject *handler = [_streamHandlers objectForKey:channelName]; - if (handler) { - [_streamHandlers removeObjectForKey:channelName]; - } - - FlutterEventChannel *channel = [_eventChannels objectForKey:channelName]; - if (channel) { - [channel setStreamHandler:nil]; - [_eventChannels removeObjectForKey:channelName]; - } - - @synchronized(self->_tasks) { - [self->_tasks removeObjectForKey:handle]; - } -} - -- (void)referencePutStringApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - data:(NSString *)data - format:(NSNumber *)format - settableMetaData:(PigeonSettableMetadata *)settableMetaData - handle:(NSNumber *)handle - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - - NSData *formatted_data = - [self NSDataFromUploadString:data format:(FLTFirebaseStorageStringType)[format intValue]]; - FIRStorageMetadata *metadata = [self getFIRStorageMetadataFromPigeon:settableMetaData]; - - FIRStorageObservableTask *task = - [storage_reference putData:formatted_data metadata:metadata]; - - @synchronized(self->_tasks) { - self->_tasks[handle] = task; - } - - completion([self setupTaskListeners:task handle:handle], nil); -} - -- (void)referencePutFileApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - filePath:(NSString *)filePath - settableMetaData:(PigeonSettableMetadata *)settableMetaData - handle:(NSNumber *)handle - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - - NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; - FIRStorageObservableTask *task; - if (settableMetaData == nil) { - task = [storage_reference putFile:fileUrl]; - } else { - FIRStorageMetadata *metadata = [self getFIRStorageMetadataFromPigeon:settableMetaData]; - task = [storage_reference putFile:fileUrl metadata:metadata]; - } - - @synchronized(self->_tasks) { - self->_tasks[handle] = task; - } - - completion([self setupTaskListeners:task handle:handle], nil); -} - -- (void)referenceDownloadFileApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - filePath:(NSString *)filePath - handle:(NSNumber *)handle - completion: - (void (^)(NSString *_Nullable, FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - - NSURL *fileUrl = [NSURL fileURLWithPath:filePath]; - FIRStorageObservableTask *task = - [storage_reference writeToFile:fileUrl]; - - @synchronized(self->_tasks) { - self->_tasks[handle] = task; - } - - completion([self setupTaskListeners:task handle:handle], nil); -} - -- (void)referenceUpdateMetadataApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - metadata:(PigeonSettableMetadata *)metadata - completion:(void (^)(PigeonFullMetaData *_Nullable, - FlutterError *_Nullable))completion { - FIRStorageReference *storage_reference = [self getFIRStorageReferenceFromPigeon:app - reference:reference]; - FIRStorageMetadata *storage_metadata = [self getFIRStorageMetadataFromPigeon:metadata]; - - [storage_reference updateMetadata:storage_metadata - completion:^(FIRStorageMetadata *updatedMetadata, NSError *error) { - if (error != nil) { - completion(nil, [self FlutterErrorFromNSError:error]); - } else { - NSDictionary *dict = [FLTFirebaseStoragePlugin - NSDictionaryFromFIRStorageMetadata:updatedMetadata]; - completion([PigeonFullMetaData makeWithMetadata:dict], nil); - } - }]; -} - -- (void)taskPauseApp:(PigeonStorageFirebaseApp *)app - handle:(NSNumber *)handle - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion { - FIRStorageObservableTask *task; - @synchronized(self->_tasks) { - task = self->_tasks[handle]; - } - if (task != nil) { - [self setState:FLTFirebaseStorageTaskStatePause - forFIRStorageObservableTask:task - withCompletion:^(BOOL success, NSDictionary *snapshotDict) { - completion( - @{ - @"status" : @(success), - @"snapshot" : (id)snapshotDict ?: [NSNull null], - }, - nil); - }]; - } else { - completion(nil, [FlutterError errorWithCode:@"unknown" - message:@"Cannot find task to pause." - details:@{}]); - } -} - -- (void)taskResumeApp:(PigeonStorageFirebaseApp *)app - handle:(NSNumber *)handle - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion { - FIRStorageObservableTask *task; - @synchronized(self->_tasks) { - task = self->_tasks[handle]; - } - if (task != nil) { - [self setState:FLTFirebaseStorageTaskStateResume - forFIRStorageObservableTask:task - withCompletion:^(BOOL success, NSDictionary *snapshotDict) { - completion( - @{ - @"status" : @(success), - @"snapshot" : (id)snapshotDict ?: [NSNull null], - }, - nil); - }]; - } else { - completion(nil, [FlutterError errorWithCode:@"unknown" - message:@"Cannot find task to resume." - details:@{}]); - } -} - -- (void)taskCancelApp:(PigeonStorageFirebaseApp *)app - handle:(NSNumber *)handle - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion { - FIRStorageObservableTask *task; - @synchronized(self->_tasks) { - task = self->_tasks[handle]; - } - if (task != nil) { - [self setState:FLTFirebaseStorageTaskStateCancel - forFIRStorageObservableTask:task - withCompletion:^(BOOL success, NSDictionary *snapshotDict) { - completion( - @{ - @"status" : @(success), - @"snapshot" : (id)snapshotDict ?: [NSNull null], - }, - nil); - }]; - } else { - completion(nil, [FlutterError errorWithCode:@"unknown" - message:@"Cannot find task to cancel." - details:@{}]); - } -} - -#pragma mark - Utilities - -// To match Web & Android SDKs we need to return a bool of whether a task state change was -// successful. -- (void)setState:(FLTFirebaseStorageTaskState)state - forFIRStorageObservableTask:(FIRStorageObservableTask *)task - withCompletion:(void (^)(BOOL, NSDictionary *))completion { - // Pause - if (state == FLTFirebaseStorageTaskStatePause) { - if (task.snapshot.status == FIRStorageTaskStatusResume || - task.snapshot.status == FIRStorageTaskStatusProgress || - task.snapshot.status == FIRStorageTaskStatusUnknown) { - __block NSString *pauseHandle; - __block NSString *successHandle; - __block NSString *failureHandle; - pauseHandle = - [task observeStatus:FIRStorageTaskStatusPause - handler:^(FIRStorageTaskSnapshot *snapshot) { - [task removeObserverWithHandle:pauseHandle]; - [task removeObserverWithHandle:successHandle]; - [task removeObserverWithHandle:failureHandle]; - completion(YES, [FLTFirebaseStoragePlugin parseTaskSnapshot:snapshot]); - }]; - successHandle = [task observeStatus:FIRStorageTaskStatusSuccess - handler:^(FIRStorageTaskSnapshot *snapshot) { - [task removeObserverWithHandle:pauseHandle]; - [task removeObserverWithHandle:successHandle]; - [task removeObserverWithHandle:failureHandle]; - completion(NO, nil); - }]; - failureHandle = [task observeStatus:FIRStorageTaskStatusFailure - handler:^(FIRStorageTaskSnapshot *snapshot) { - [task removeObserverWithHandle:pauseHandle]; - [task removeObserverWithHandle:successHandle]; - [task removeObserverWithHandle:failureHandle]; - completion(NO, nil); - }]; - - [task pause]; - } else { - completion(NO, nil); - } - return; - } - - // Resume - if (state == FLTFirebaseStorageTaskStateResume) { - if (task.snapshot.status == FIRStorageTaskStatusPause) { - __block NSString *resumeHandle; - __block NSString *progressHandle; - __block NSString *successHandle; - __block NSString *failureHandle; - resumeHandle = - [task observeStatus:FIRStorageTaskStatusResume - handler:^(FIRStorageTaskSnapshot *snapshot) { - [task removeObserverWithHandle:resumeHandle]; - [task removeObserverWithHandle:progressHandle]; - [task removeObserverWithHandle:successHandle]; - [task removeObserverWithHandle:failureHandle]; - completion(YES, [FLTFirebaseStoragePlugin parseTaskSnapshot:snapshot]); - }]; - progressHandle = - [task observeStatus:FIRStorageTaskStatusProgress - handler:^(FIRStorageTaskSnapshot *snapshot) { - [task removeObserverWithHandle:resumeHandle]; - [task removeObserverWithHandle:progressHandle]; - [task removeObserverWithHandle:successHandle]; - [task removeObserverWithHandle:failureHandle]; - completion(YES, [FLTFirebaseStoragePlugin parseTaskSnapshot:snapshot]); - }]; - successHandle = [task observeStatus:FIRStorageTaskStatusSuccess - handler:^(FIRStorageTaskSnapshot *snapshot) { - [task removeObserverWithHandle:resumeHandle]; - [task removeObserverWithHandle:progressHandle]; - [task removeObserverWithHandle:successHandle]; - [task removeObserverWithHandle:failureHandle]; - completion(NO, nil); - }]; - failureHandle = [task observeStatus:FIRStorageTaskStatusFailure - handler:^(FIRStorageTaskSnapshot *snapshot) { - [task removeObserverWithHandle:resumeHandle]; - [task removeObserverWithHandle:progressHandle]; - [task removeObserverWithHandle:successHandle]; - [task removeObserverWithHandle:failureHandle]; - completion(NO, nil); - }]; - [task resume]; - } else { - completion(NO, nil); - } - return; - } - - // Cancel - if (state == FLTFirebaseStorageTaskStateCancel) { - if (task.snapshot.status == FIRStorageTaskStatusPause || - task.snapshot.status == FIRStorageTaskStatusResume || - task.snapshot.status == FIRStorageTaskStatusProgress || - task.snapshot.status == FIRStorageTaskStatusUnknown) { - __block NSString *successHandle; - __block NSString *failureHandle; - successHandle = [task observeStatus:FIRStorageTaskStatusSuccess - handler:^(FIRStorageTaskSnapshot *snapshot) { - [task removeObserverWithHandle:successHandle]; - [task removeObserverWithHandle:failureHandle]; - completion(NO, nil); - }]; - failureHandle = [task - observeStatus:FIRStorageTaskStatusFailure - handler:^(FIRStorageTaskSnapshot *snapshot) { - [task removeObserverWithHandle:successHandle]; - [task removeObserverWithHandle:failureHandle]; - - if (snapshot.error && snapshot.error && snapshot.error.userInfo) { - // For UploadTask, the error code is found in the userInfo - // We use it to match this: - // https://github.com/firebase/firebase-ios-sdk/blob/main/FirebaseStorage/Sources/StorageError.swift#L37 - NSNumber *responseErrorCode = snapshot.error.userInfo[@"ResponseErrorCode"]; - if ([responseErrorCode integerValue] == FIRStorageErrorCodeCancelled || - snapshot.error.code == FIRStorageErrorCodeCancelled) { - completion(YES, [FLTFirebaseStoragePlugin parseTaskSnapshot:snapshot]); - return; - } - } - - completion(NO, nil); - }]; - [task cancel]; - } else { - completion(NO, nil); - } - return; - } - - completion(NO, nil); -} - -+ (NSDictionary *)NSDictionaryFromNSError:(NSError *)error { - NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; - NSString *code = @"unknown"; - NSString *message = [error localizedDescription]; - - if (error.code == FIRStorageErrorCodeUnknown) { - code = @"unknown"; - } else if (error.code == FIRStorageErrorCodeObjectNotFound) { - code = @"object-not-found"; - message = @"No object exists at the desired reference."; - } else if (error.code == FIRStorageErrorCodeBucketNotFound) { - code = @"bucket-not-found"; - message = @"No bucket is configured for Firebase Storage."; - } else if (error.code == FIRStorageErrorCodeProjectNotFound) { - code = @"project-not-found"; - message = @"No project is configured for Firebase Storage."; - } else if (error.code == FIRStorageErrorCodeQuotaExceeded) { - code = @"quota-exceeded"; - message = @"Quota on your Firebase Storage bucket has been exceeded."; - } else if (error.code == FIRStorageErrorCodeUnauthenticated) { - code = @"unauthenticated"; - message = @"User is unauthenticated. Authenticate and try again."; - } else if (error.code == FIRStorageErrorCodeUnauthorized) { - code = @"unauthorized"; - message = @"User is not authorized to perform the desired action."; - } else if (error.code == FIRStorageErrorCodeRetryLimitExceeded) { - code = @"retry-limit-exceeded"; - message = @"The maximum time limit on an operation (upload, download, delete, etc.) has been " - @"exceeded."; - } else if (error.code == FIRStorageErrorCodeNonMatchingChecksum) { - code = @"invalid-checksum"; - message = @"File on the client does not match the checksum of the file received by the server."; - } else if (error.code == FIRStorageErrorCodeDownloadSizeExceeded) { - code = @"download-size-exceeded"; - message = - @"Size of the downloaded file exceeds the amount of memory allocated for the download."; - } else if (error.code == FIRStorageErrorCodeCancelled) { - code = @"canceled"; - message = @"User cancelled the operation."; - } else if (error.code == FIRStorageErrorCodeInvalidArgument) { - code = @"invalid-argument"; - } - - dictionary[@"code"] = code; - dictionary[@"message"] = message; - - return dictionary; -} - -- (FlutterError *_Nullable)FlutterErrorFromNSError:(NSError *_Nullable)error { - if (error == nil) { - return nil; - } - NSDictionary *dictionary = [FLTFirebaseStoragePlugin NSDictionaryFromNSError:error]; - return [FlutterError errorWithCode:dictionary[@"code"] - message:dictionary[@"message"] - details:@{}]; -} - -- (NSDictionary *)NSDictionaryFromHandle:(NSNumber *)handle - andFIRStorageTaskSnapshot:(FIRStorageTaskSnapshot *)snapshot { - NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; - dictionary[kFLTFirebaseStorageKeyHandle] = handle; - dictionary[kFLTFirebaseStorageKeyAppName] = - [FLTFirebasePlugin firebaseAppNameFromIosName:snapshot.reference.storage.app.name]; - dictionary[kFLTFirebaseStorageKeyBucket] = snapshot.reference.bucket; - if (snapshot.error != nil) { - dictionary[@"error"] = [FLTFirebaseStoragePlugin NSDictionaryFromNSError:snapshot.error]; - } else { - dictionary[kFLTFirebaseStorageKeySnapshot] = - [FLTFirebaseStoragePlugin parseTaskSnapshot:snapshot]; - } - return dictionary; -} - -+ (NSDictionary *)parseTaskSnapshot:(FIRStorageTaskSnapshot *)snapshot { - NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; - - dictionary[kFLTFirebaseStorageKeyPath] = snapshot.reference.fullPath; - - if (snapshot.metadata != nil) { - dictionary[@"metadata"] = - [FLTFirebaseStoragePlugin NSDictionaryFromFIRStorageMetadata:snapshot.metadata]; - } - - if (snapshot.progress != nil) { - dictionary[@"bytesTransferred"] = @(snapshot.progress.completedUnitCount); - dictionary[@"totalBytes"] = @(snapshot.progress.totalUnitCount); - } else { - dictionary[@"bytesTransferred"] = @(0); - dictionary[@"totalBytes"] = @(0); - } - - return dictionary; -} - -- (NSData *)NSDataFromUploadString:(NSString *)string format:(FLTFirebaseStorageStringType)format { - // Dart: PutStringFormat.base64 - if (format == FLTFirebaseStorageStringTypeBase64) { - return [[NSData alloc] initWithBase64EncodedString:string options:0]; - } - - // Dart: PutStringFormat.base64Url - if (format == FLTFirebaseStorageStringTypeBase64URL) { - // Convert to base64 from base64url. - NSString *base64Encoded = string; - base64Encoded = [base64Encoded stringByReplacingOccurrencesOfString:@"-" withString:@"+"]; - base64Encoded = [base64Encoded stringByReplacingOccurrencesOfString:@"_" withString:@"/"]; - // Add mandatory base64 encoding padding. - while (base64Encoded.length % 4 != 0) { - base64Encoded = [base64Encoded stringByAppendingString:@"="]; - } - - return [[NSData alloc] initWithBase64EncodedString:base64Encoded options:0]; - } - - return nil; -} - -- (NSDictionary *)NSDictionaryFromFIRStorageListResult:(FIRStorageListResult *)listResult { - NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; - - NSMutableArray *items = [[NSMutableArray alloc] init]; - for (FIRStorageReference *reference in listResult.items) { - [items addObject:reference.fullPath]; - } - dictionary[kFLTFirebaseStorageKeyItems] = items; - - NSMutableArray *prefixes = [[NSMutableArray alloc] init]; - for (FIRStorageReference *reference in listResult.prefixes) { - [prefixes addObject:reference.fullPath]; - } - dictionary[kFLTFirebaseStorageKeyPrefixes] = prefixes; - - if (listResult.pageToken != nil) { - dictionary[kFLTFirebaseStorageKeyNextPageToken] = listResult.pageToken; - } - - return dictionary; -} - -+ (NSDictionary *)NSDictionaryFromFIRStorageMetadata:(FIRStorageMetadata *)metadata { - NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; - - [dictionary setValue:[metadata name] forKey:kFLTFirebaseStorageKeyName]; - [dictionary setValue:[metadata bucket] forKey:kFLTFirebaseStorageKeyBucket]; - - [dictionary setValue:[NSString stringWithFormat:@"%lld", [metadata generation]] - forKey:kFLTFirebaseStorageKeyGeneration]; - - [dictionary setValue:[NSString stringWithFormat:@"%lld", [metadata metageneration]] - forKey:kFLTFirebaseStorageKeyMetadataGeneration]; - - [dictionary setValue:[metadata path] forKey:kFLTFirebaseStorageKeyFullPath]; - - [dictionary setValue:@([metadata size]) forKey:kFLTFirebaseStorageKeySize]; - - [dictionary setValue:@((long)([[metadata timeCreated] timeIntervalSince1970] * 1000.0)) - forKey:kFLTFirebaseStorageKeyCreationTime]; - - [dictionary setValue:@((long)([[metadata updated] timeIntervalSince1970] * 1000.0)) - forKey:kFLTFirebaseStorageKeyUpdatedTime]; - - if ([metadata md5Hash] != nil) { - [dictionary setValue:[metadata md5Hash] forKey:kFLTFirebaseStorageKeyMD5Hash]; - } - - if ([metadata cacheControl] != nil) { - [dictionary setValue:[metadata cacheControl] forKey:kFLTFirebaseStorageKeyCacheControl]; - } - - if ([metadata contentDisposition] != nil) { - [dictionary setValue:[metadata contentDisposition] - forKey:kFLTFirebaseStorageKeyContentDisposition]; - } - - if ([metadata contentEncoding] != nil) { - [dictionary setValue:[metadata contentEncoding] forKey:kFLTFirebaseStorageKeyContentEncoding]; - } - - if ([metadata contentLanguage] != nil) { - [dictionary setValue:[metadata contentLanguage] forKey:kFLTFirebaseStorageKeyContentLanguage]; - } - - if ([metadata contentType] != nil) { - [dictionary setValue:[metadata contentType] forKey:kFLTFirebaseStorageKeyContentType]; - } - - if ([metadata customMetadata] != nil) { - [dictionary setValue:[metadata customMetadata] forKey:kFLTFirebaseStorageKeyCustomMetadata]; - } else { - [dictionary setValue:@{} forKey:kFLTFirebaseStorageKeyCustomMetadata]; - } - - return dictionary; -} - -#pragma mark - FLTFirebasePlugin - -- (void)didReinitializeFirebaseCore:(void (^)(void))completion { - [self cleanupWithCompletion:completion]; -} - -- (NSDictionary *_Nonnull)pluginConstantsForFIRApp:(FIRApp *)firebase_app { - return @{}; -} - -- (NSString *_Nonnull)firebaseLibraryName { - return @LIBRARY_NAME; -} - -- (NSString *_Nonnull)firebaseLibraryVersion { - return @LIBRARY_VERSION; -} - -- (NSString *_Nonnull)flutterChannelName { - return kFLTFirebaseStorageChannelName; -} - -@end diff --git a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.swift b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.swift new file mode 100644 index 000000000000..2696d2c9f94d --- /dev/null +++ b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.swift @@ -0,0 +1,390 @@ +// Copyright 2025 The Chromium Authors. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import FirebaseStorage +import Foundation + +#if canImport(firebase_core) + import firebase_core +#else + import firebase_core_shared +#endif + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#endif + +extension FlutterError: Error {} + +public final class FLTFirebaseStoragePlugin: NSObject, FlutterPlugin, FirebaseStorageHostApi { + private var channel: FlutterMethodChannel? + private var messenger: FlutterBinaryMessenger? + private var eventChannels: [String: FlutterEventChannel] = [:] + private var streamHandlers: [String: FlutterStreamHandler] = [:] + private var handleToTask: [Int64: AnyObject] = [:] + private var handleToPath: [Int64: String] = [:] + private var handleToIdentifier: [Int64: String] = [:] + + // Registry to help stream handler classify failure events as cancellations when initiated from + // Dart + static var canceledIdentifiers = Set() + + @objc + public static func register(with registrar: FlutterPluginRegistrar) { + let channelName = "plugins.flutter.io/firebase_storage" + // Resolve platform-specific messenger API differences + #if os(iOS) + let resolvedMessenger: FlutterBinaryMessenger = registrar.messenger() + #else + let resolvedMessenger: FlutterBinaryMessenger = registrar.messenger + #endif + let channel = FlutterMethodChannel(name: channelName, binaryMessenger: resolvedMessenger) + let instance = FLTFirebaseStoragePlugin() + instance.channel = channel + instance.messenger = resolvedMessenger + registrar.addMethodCallDelegate(instance, channel: channel) + FirebaseStorageHostApiSetup.setUp(binaryMessenger: resolvedMessenger, api: instance) + } + + public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { + result(FlutterMethodNotImplemented) + } + + private func storage(app: PigeonStorageFirebaseApp) -> Storage { + let base = "gs://" + app.bucket + let firApp = FLTFirebasePlugin.firebaseAppNamed(app.appName)! + return Storage.storage(app: firApp, url: base) + } + + private func ref(app: PigeonStorageFirebaseApp, + reference: PigeonStorageReference) -> StorageReference { + storage(app: app).reference(withPath: reference.fullPath) + } + + private func toPigeon(_ ref: StorageReference) -> PigeonStorageReference { + PigeonStorageReference(bucket: ref.bucket, fullPath: ref.fullPath, name: ref.name) + } + + func getReferencebyPath(app: PigeonStorageFirebaseApp, path: String, bucket: String?, + completion: @escaping (Result) -> Void) { + let r = storage(app: app).reference(withPath: path) + completion(.success(PigeonStorageReference( + bucket: r.bucket, + fullPath: r.fullPath, + name: r.name + ))) + } + + func setMaxOperationRetryTime(app: PigeonStorageFirebaseApp, time: Int64, + completion: @escaping (Result) -> Void) { + storage(app: app).maxOperationRetryTime = TimeInterval(Double(time) / 1000.0) + completion(.success(())) + } + + func setMaxUploadRetryTime(app: PigeonStorageFirebaseApp, time: Int64, + completion: @escaping (Result) -> Void) { + storage(app: app).maxUploadRetryTime = TimeInterval(Double(time) / 1000.0) + completion(.success(())) + } + + func setMaxDownloadRetryTime(app: PigeonStorageFirebaseApp, time: Int64, + completion: @escaping (Result) -> Void) { + storage(app: app).maxDownloadRetryTime = TimeInterval(Double(time) / 1000.0) + completion(.success(())) + } + + func useStorageEmulator(app: PigeonStorageFirebaseApp, host: String, port: Int64, + completion: @escaping (Result) -> Void) { + let s = storage(app: app) + s.useEmulator(withHost: host, port: Int(port)) + completion(.success(())) + } + + func referenceDelete(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + completion: @escaping (Result) -> Void) { + ref(app: app, reference: reference).delete { error in + if let e = error { completion(.failure(self.toFlutterError(e))) } + else { completion(.success(())) } + } + } + + func referenceGetDownloadURL(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + completion: @escaping (Result) -> Void) { + ref(app: app, reference: reference).downloadURL { url, error in + if let e = error { completion(.failure(self.toFlutterError(e))) } + else { completion(.success(url!.absoluteString.replacingOccurrences( + of: ":443", + with: "" + ))) } + } + } + + func referenceGetMetaData(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + completion: @escaping (Result) -> Void) { + ref(app: app, reference: reference).getMetadata { md, error in + if let e = error { completion(.failure(self.toFlutterError(e))) } else { + completion(.success(PigeonFullMetaData(metadata: self.metaToDict(md)))) + } + } + } + + func referenceList(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + options: PigeonListOptions, + completion: @escaping (Result) -> Void) { + let r = ref(app: app, reference: reference) + let block: (StorageListResult?, Error?) -> Void = { list, error in + if let e = error { completion(.failure(self.toFlutterError(e))) } else { + completion(.success(self.listToPigeon(list!))) + } + } + if let token = options.pageToken { + r.list(maxResults: options.maxResults, pageToken: token, completion: block) + } else { + r.list(maxResults: options.maxResults, completion: block) + } + } + + func referenceListAll(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + completion: @escaping (Result) -> Void) { + ref(app: app, reference: reference).listAll { list, error in + if let e = error { completion(.failure(self.toFlutterError(e))) } + else { completion(.success(self.listToPigeon(list!))) } + } + } + + func referenceGetData(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + maxSize: Int64, + completion: @escaping (Result) -> Void) { + ref(app: app, reference: reference).getData(maxSize: maxSize) { data, error in + if let e = error { + completion(.failure(self.toFlutterError(e))) + } else if let data { + completion(.success(FlutterStandardTypedData(bytes: data))) + } else { + completion(.success(nil)) + } + } + } + + func referencePutData(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + data: FlutterStandardTypedData, settableMetaData: PigeonSettableMetadata, + handle: Int64, completion: @escaping (Result) -> Void) { + let r = ref(app: app, reference: reference) + let task = r.putData(data.data, metadata: toMeta(settableMetaData)) + completion(.success(registerTask( + task: task, + appName: r.storage.app.name, + handle: handle, + path: r.fullPath + ))) + } + + func referencePutString(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + data: String, format: Int64, settableMetaData: PigeonSettableMetadata, + handle: Int64, completion: @escaping (Result) -> Void) { + let r = ref(app: app, reference: reference) + let d: Data + if format == 1 { d = Data(base64Encoded: data) ?? Data() } + else if format == + 2 { + d = Data(base64Encoded: data.replacingOccurrences(of: "-", with: "+") + .replacingOccurrences(of: "_", with: "/") + .padding(toLength: ((data.count + 3) / 4) * 4, withPad: "=", startingAt: 0)) ?? Data() + } else { d = Data() } + let task = r.putData(d, metadata: toMeta(settableMetaData)) + completion(.success(registerTask( + task: task, + appName: r.storage.app.name, + handle: handle, + path: r.fullPath + ))) + } + + func referencePutFile(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + filePath: String, settableMetaData: PigeonSettableMetadata?, handle: Int64, + completion: @escaping (Result) -> Void) { + let r = ref(app: app, reference: reference) + let url = URL(fileURLWithPath: filePath) + let task: StorageUploadTask + if let md = settableMetaData { task = r.putFile(from: url, metadata: toMeta(md)) } + else { task = r.putFile(from: url) } + completion(.success(registerTask( + task: task, + appName: r.storage.app.name, + handle: handle, + path: r.fullPath + ))) + } + + func referenceDownloadFile(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + filePath: String, handle: Int64, + completion: @escaping (Result) -> Void) { + let r = ref(app: app, reference: reference) + let url = URL(fileURLWithPath: filePath) + let task = r.write(toFile: url) + completion(.success(registerTask( + task: task, + appName: r.storage.app.name, + handle: handle, + path: r.fullPath + ))) + } + + func referenceUpdateMetadata(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + metadata: PigeonSettableMetadata, + completion: @escaping (Result) -> Void) { + ref(app: app, reference: reference).updateMetadata(toMeta(metadata)) { md, error in + if let e = error { completion(.failure(self.toFlutterError(e))) } + else { completion(.success(PigeonFullMetaData(metadata: self.metaToDict(md)))) } + } + } + + func taskPause(app: PigeonStorageFirebaseApp, handle: Int64, + completion: @escaping (Result<[String: Any], Error>) -> Void) { + if let task = handleToTask[handle] as? StorageUploadTask { + task.pause() + completion(.success(["status": true, "snapshot": currentSnapshot(handle: handle)])) + } else if let task = handleToTask[handle] as? StorageDownloadTask { + task.pause() + completion(.success(["status": true, "snapshot": currentSnapshot(handle: handle)])) + } else { + completion(.success(["status": false])) + } + } + + func taskResume(app: PigeonStorageFirebaseApp, handle: Int64, + completion: @escaping (Result<[String: Any], Error>) -> Void) { + if let task = handleToTask[handle] as? StorageUploadTask { + task.resume() + completion(.success(["status": true, "snapshot": currentSnapshot(handle: handle)])) + } else if let task = handleToTask[handle] as? StorageDownloadTask { + task.resume() + completion(.success(["status": true, "snapshot": currentSnapshot(handle: handle)])) + } else { + completion(.success(["status": false])) + } + } + + func taskCancel(app: PigeonStorageFirebaseApp, handle: Int64, + completion: @escaping (Result<[String: Any], Error>) -> Void) { + if let task = handleToTask[handle] as? StorageUploadTask { + task.cancel() + if let id = handleToIdentifier[handle] { + FLTFirebaseStoragePlugin.canceledIdentifiers.insert(id) + } + completion(.success(["status": true, "snapshot": currentSnapshot(handle: handle)])) + } else if let task = handleToTask[handle] as? StorageDownloadTask { + task.cancel() + if let id = handleToIdentifier[handle] { + FLTFirebaseStoragePlugin.canceledIdentifiers.insert(id) + } + completion(.success(["status": true, "snapshot": currentSnapshot(handle: handle)])) + } else { + completion(.success(["status": false])) + } + } + + private func toMeta(_ m: PigeonSettableMetadata) -> StorageMetadata { + let md = StorageMetadata() + if let v = m.cacheControl { md.cacheControl = v } + if let v = m.contentType { md.contentType = v } + if let v = m.contentDisposition { md.contentDisposition = v } + if let v = m.contentEncoding { md.contentEncoding = v } + if let v = m.contentLanguage { md.contentLanguage = v } + if let v = m.customMetadata { md.customMetadata = v as? [String: String] } + return md + } + + private func metaToDict(_ md: StorageMetadata?) -> [String: Any]? { + guard let md else { return nil } + var out: [String: Any] = [:] + out["name"] = md.name + out["bucket"] = md.bucket + out["generation"] = String(md.generation) + out["metadataGeneration"] = String(md.metageneration) + out["fullPath"] = md.path + out["size"] = md.size + out["creationTimeMillis"] = Int((md.timeCreated?.timeIntervalSince1970 ?? 0) * 1000) + out["updatedTimeMillis"] = Int((md.updated?.timeIntervalSince1970 ?? 0) * 1000) + if let v = md.md5Hash { out["md5Hash"] = v } + if let v = md.cacheControl { out["cacheControl"] = v } + if let v = md.contentDisposition { out["contentDisposition"] = v } + if let v = md.contentEncoding { out["contentEncoding"] = v } + if let v = md.contentLanguage { out["contentLanguage"] = v } + if let v = md.contentType { out["contentType"] = v } + out["customMetadata"] = md.customMetadata ?? [:] + return out + } + + private func listToPigeon(_ list: StorageListResult) -> PigeonListResult { + let items = list.items.map { toPigeon($0) } + let prefixes = list.prefixes.map { toPigeon($0) } + let itemsOpt: [PigeonStorageReference?] = items.map { Optional($0) } + let prefixesOpt: [PigeonStorageReference?] = prefixes.map { Optional($0) } + return PigeonListResult(items: itemsOpt, pageToken: list.pageToken, prefixs: prefixesOpt) + } + + private func registerTask(task: StorageObservableTask, appName: String, handle: Int64, + path: String) -> String { + let uuid = UUID().uuidString + let channelName = "plugins.flutter.io/firebase_storage/taskEvent/\(uuid)" + let channel = FlutterEventChannel(name: channelName, binaryMessenger: messenger!) + let storageInstance = Storage.storage(app: FLTFirebasePlugin.firebaseAppNamed(appName)!) + channel.setStreamHandler(TaskStateChannelStreamHandler( + task: task, + storage: storageInstance, + identifier: channelName + )) + eventChannels[channelName] = channel + handleToTask[handle] = task as AnyObject + handleToPath[handle] = path + handleToIdentifier[handle] = channelName + return uuid + } + + private func currentSnapshot(handle: Int64) -> [String: Any] { + [ + "path": handleToPath[handle] ?? "", + "bytesTransferred": 0, + "totalBytes": 0, + ] + } + + private func toFlutterError(_ error: Error) -> Error { + let ns = error as NSError + let code = mapStorageErrorCode(ns) + let message = standardMessage(for: code) ?? ns.localizedDescription + return FlutterError(code: code, message: message, details: [:]) + } + + private func mapStorageErrorCode(_ error: NSError) -> String { + if error.domain == StorageErrorDomain, let code = StorageErrorCode(rawValue: error.code) { + switch code { + case .objectNotFound: return "object-not-found" + case .bucketNotFound: return "bucket-not-found" + case .projectNotFound: return "project-not-found" + case .quotaExceeded: return "quota-exceeded" + case .unauthenticated: return "unauthenticated" + case .unauthorized: return "unauthorized" + case .retryLimitExceeded: return "retry-limit-exceeded" + case .cancelled: return "canceled" + case .downloadSizeExceeded: return "download-size-exceeded" + @unknown default: return "unknown" + } + } else if error.domain == NSURLErrorDomain, error.code == NSURLErrorCancelled { + return "canceled" + } + return "unknown" + } + + private func standardMessage(for code: String) -> String? { + switch code { + case "object-not-found": return "No object exists at the desired reference." + case "unauthorized": return "User is not authorized to perform the desired action." + default: return nil + } + } +} diff --git a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FLTTaskStateChannelStreamHandler.m b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FLTTaskStateChannelStreamHandler.m deleted file mode 100644 index 348c275ab527..000000000000 --- a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FLTTaskStateChannelStreamHandler.m +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2023 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -@import FirebaseStorage; - -#import "FLTTaskStateChannelStreamHandler.h" -#import "FLTFirebaseStoragePlugin.h" - -@implementation FLTTaskStateChannelStreamHandler { - FIRStorageObservableTask *_task; - FLTFirebaseStoragePlugin *_storagePlugin; - NSString *_channelName; - NSNumber *_handle; - NSString *successHandle; - NSString *failureHandle; - NSString *pausedHandle; - NSString *progressHandle; -} - -- (instancetype)initWithTask:(FIRStorageObservableTask *)task - storagePlugin:(FLTFirebaseStoragePlugin *)storagePlugin - channelName:(NSString *)channelName - handle:(NSNumber *)handle { - self = [super init]; - if (self) { - _task = task; - _storagePlugin = storagePlugin; - _channelName = channelName; - _handle = handle; - } - return self; -} - -- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events { - // Set up the various status listeners - successHandle = - [_task observeStatus:FIRStorageTaskStatusSuccess - handler:^(FIRStorageTaskSnapshot *snapshot) { - events(@{ - @"taskState" : @(PigeonStorageTaskStateSuccess), - @"appName" : snapshot.reference.storage.app.name, - @"snapshot" : [FLTFirebaseStoragePlugin parseTaskSnapshot:snapshot], - }); - }]; - failureHandle = - [_task observeStatus:FIRStorageTaskStatusFailure - handler:^(FIRStorageTaskSnapshot *snapshot) { - NSError *error = snapshot.error; - // If the snapshot.error is "unknown" and there is an underlying error, use - // this. For UploadTasks, the correct error is in the underlying error. - if (snapshot.error.code == FIRStorageErrorCodeUnknown && - snapshot.error.userInfo[@"NSUnderlyingError"] != nil) { - error = snapshot.error.userInfo[@"NSUnderlyingError"]; - } - events(@{ - @"taskState" : @(PigeonStorageTaskStateError), - @"appName" : snapshot.reference.storage.app.name, - @"error" : [FLTFirebaseStoragePlugin NSDictionaryFromNSError:error], - }); - }]; - pausedHandle = - [_task observeStatus:FIRStorageTaskStatusPause - handler:^(FIRStorageTaskSnapshot *snapshot) { - events(@{ - @"taskState" : @(PigeonStorageTaskStatePaused), - @"appName" : snapshot.reference.storage.app.name, - @"snapshot" : [FLTFirebaseStoragePlugin parseTaskSnapshot:snapshot], - }); - }]; - progressHandle = - [_task observeStatus:FIRStorageTaskStatusProgress - handler:^(FIRStorageTaskSnapshot *snapshot) { - events(@{ - @"taskState" : @(PigeonStorageTaskStateRunning), - @"appName" : snapshot.reference.storage.app.name, - @"snapshot" : [FLTFirebaseStoragePlugin parseTaskSnapshot:snapshot], - }); - }]; - - return nil; -} - -- (FlutterError *)onCancelWithArguments:(id)arguments { - if (!_task) { - return nil; - } - - if (successHandle) { - [_task removeObserverWithHandle:successHandle]; - } - successHandle = nil; - - if (failureHandle) { - [_task removeObserverWithHandle:failureHandle]; - } - failureHandle = nil; - - if (pausedHandle) { - [_task removeObserverWithHandle:pausedHandle]; - } - pausedHandle = nil; - - if (progressHandle) { - [_task removeObserverWithHandle:progressHandle]; - } - progressHandle = nil; - - if (_storagePlugin) { - [_storagePlugin cleanUpTask:_channelName handle:_handle]; - } - - return nil; -} - -@end diff --git a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FirebaseStorageMessages.g.swift b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FirebaseStorageMessages.g.swift new file mode 100644 index 000000000000..35094d379e30 --- /dev/null +++ b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/FirebaseStorageMessages.g.swift @@ -0,0 +1,823 @@ +// Copyright 2023, the Chromium project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. +// Autogenerated from Pigeon (v11.0.1), do not edit directly. +// See also: https://pub.dev/packages/pigeon + +import Foundation +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#else + #error("Unsupported platform.") +#endif + +private func isNullish(_ value: Any?) -> Bool { + value is NSNull || value == nil +} + +private func wrapResult(_ result: Any?) -> [Any?] { + [result] +} + +private func wrapError(_ error: Any) -> [Any?] { + if let flutterError = error as? FlutterError { + return [ + flutterError.code, + flutterError.message, + flutterError.details, + ] + } + return [ + "\(error)", + "\(type(of: error))", + "Stacktrace: \(Thread.callStackSymbols)", + ] +} + +private func nilOrValue(_ value: Any?) -> T? { + if value is NSNull { return nil } + return value as! T? +} + +/// The type of operation that generated the action code from calling +/// [TaskState]. +enum PigeonStorageTaskState: Int { + /// Indicates the task has been paused by the user. + case paused = 0 + /// Indicates the task is currently in-progress. + case running = 1 + /// Indicates the task has successfully completed. + case success = 2 + /// Indicates the task was canceled. + case canceled = 3 + /// Indicates the task failed with an error. + case error = 4 +} + +/// Generated class from Pigeon that represents data sent in messages. +struct PigeonStorageFirebaseApp { + var appName: String + var tenantId: String? + var bucket: String + + static func fromList(_ list: [Any?]) -> PigeonStorageFirebaseApp? { + let appName = list[0] as! String + let tenantId: String? = nilOrValue(list[1]) + let bucket = list[2] as! String + + return PigeonStorageFirebaseApp( + appName: appName, + tenantId: tenantId, + bucket: bucket + ) + } + + func toList() -> [Any?] { + [ + appName, + tenantId, + bucket, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct PigeonStorageReference { + var bucket: String + var fullPath: String + var name: String + + static func fromList(_ list: [Any?]) -> PigeonStorageReference? { + let bucket = list[0] as! String + let fullPath = list[1] as! String + let name = list[2] as! String + + return PigeonStorageReference( + bucket: bucket, + fullPath: fullPath, + name: name + ) + } + + func toList() -> [Any?] { + [ + bucket, + fullPath, + name, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct PigeonFullMetaData { + var metadata: [String?: Any?]? + + static func fromList(_ list: [Any?]) -> PigeonFullMetaData? { + let metadata: [String?: Any?]? = nilOrValue(list[0]) + + return PigeonFullMetaData( + metadata: metadata + ) + } + + func toList() -> [Any?] { + [ + metadata, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct PigeonListOptions { + /// If set, limits the total number of `prefixes` and `items` to return. + /// + /// The default and maximum maxResults is 1000. + var maxResults: Int64 + /// The nextPageToken from a previous call to list(). + /// + /// If provided, listing is resumed from the previous position. + var pageToken: String? + + static func fromList(_ list: [Any?]) -> PigeonListOptions? { + let maxResults = list[0] is Int64 ? list[0] as! Int64 : Int64(list[0] as! Int32) + let pageToken: String? = nilOrValue(list[1]) + + return PigeonListOptions( + maxResults: maxResults, + pageToken: pageToken + ) + } + + func toList() -> [Any?] { + [ + maxResults, + pageToken, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct PigeonSettableMetadata { + /// Served as the 'Cache-Control' header on object download. + /// + /// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control. + var cacheControl: String? + /// Served as the 'Content-Disposition' header on object download. + /// + /// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition. + var contentDisposition: String? + /// Served as the 'Content-Encoding' header on object download. + /// + /// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding. + var contentEncoding: String? + /// Served as the 'Content-Language' header on object download. + /// + /// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language. + var contentLanguage: String? + /// Served as the 'Content-Type' header on object download. + /// + /// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type. + var contentType: String? + /// Additional user-defined custom metadata. + var customMetadata: [String?: String?]? + + static func fromList(_ list: [Any?]) -> PigeonSettableMetadata? { + let cacheControl: String? = nilOrValue(list[0]) + let contentDisposition: String? = nilOrValue(list[1]) + let contentEncoding: String? = nilOrValue(list[2]) + let contentLanguage: String? = nilOrValue(list[3]) + let contentType: String? = nilOrValue(list[4]) + let customMetadata: [String?: String?]? = nilOrValue(list[5]) + + return PigeonSettableMetadata( + cacheControl: cacheControl, + contentDisposition: contentDisposition, + contentEncoding: contentEncoding, + contentLanguage: contentLanguage, + contentType: contentType, + customMetadata: customMetadata + ) + } + + func toList() -> [Any?] { + [ + cacheControl, + contentDisposition, + contentEncoding, + contentLanguage, + contentType, + customMetadata, + ] + } +} + +/// Generated class from Pigeon that represents data sent in messages. +struct PigeonListResult { + var items: [PigeonStorageReference?] + var pageToken: String? + var prefixs: [PigeonStorageReference?] + + static func fromList(_ list: [Any?]) -> PigeonListResult? { + let items = list[0] as! [PigeonStorageReference?] + let pageToken: String? = nilOrValue(list[1]) + let prefixs = list[2] as! [PigeonStorageReference?] + + return PigeonListResult( + items: items, + pageToken: pageToken, + prefixs: prefixs + ) + } + + func toList() -> [Any?] { + [ + items, + pageToken, + prefixs, + ] + } +} + +private class FirebaseStorageHostApiCodecReader: FlutterStandardReader { + override func readValue(ofType type: UInt8) -> Any? { + switch type { + case 128: + return PigeonFullMetaData.fromList(readValue() as! [Any?]) + case 129: + return PigeonListOptions.fromList(readValue() as! [Any?]) + case 130: + return PigeonListResult.fromList(readValue() as! [Any?]) + case 131: + return PigeonSettableMetadata.fromList(readValue() as! [Any?]) + case 132: + return PigeonStorageFirebaseApp.fromList(readValue() as! [Any?]) + case 133: + return PigeonStorageReference.fromList(readValue() as! [Any?]) + default: + return super.readValue(ofType: type) + } + } +} + +private class FirebaseStorageHostApiCodecWriter: FlutterStandardWriter { + override func writeValue(_ value: Any) { + if let value = value as? PigeonFullMetaData { + super.writeByte(128) + super.writeValue(value.toList()) + } else if let value = value as? PigeonListOptions { + super.writeByte(129) + super.writeValue(value.toList()) + } else if let value = value as? PigeonListResult { + super.writeByte(130) + super.writeValue(value.toList()) + } else if let value = value as? PigeonSettableMetadata { + super.writeByte(131) + super.writeValue(value.toList()) + } else if let value = value as? PigeonStorageFirebaseApp { + super.writeByte(132) + super.writeValue(value.toList()) + } else if let value = value as? PigeonStorageReference { + super.writeByte(133) + super.writeValue(value.toList()) + } else { + super.writeValue(value) + } + } +} + +private class FirebaseStorageHostApiCodecReaderWriter: FlutterStandardReaderWriter { + override func reader(with data: Data) -> FlutterStandardReader { + FirebaseStorageHostApiCodecReader(data: data) + } + + override func writer(with data: NSMutableData) -> FlutterStandardWriter { + FirebaseStorageHostApiCodecWriter(data: data) + } +} + +class FirebaseStorageHostApiCodec: FlutterStandardMessageCodec { + static let shared = + FirebaseStorageHostApiCodec(readerWriter: FirebaseStorageHostApiCodecReaderWriter()) +} + +/// Generated protocol from Pigeon that represents a handler of messages from Flutter. +protocol FirebaseStorageHostApi { + func getReferencebyPath(app: PigeonStorageFirebaseApp, path: String, bucket: String?, + completion: @escaping (Result) -> Void) + func setMaxOperationRetryTime(app: PigeonStorageFirebaseApp, time: Int64, + completion: @escaping (Result) -> Void) + func setMaxUploadRetryTime(app: PigeonStorageFirebaseApp, time: Int64, + completion: @escaping (Result) -> Void) + func setMaxDownloadRetryTime(app: PigeonStorageFirebaseApp, time: Int64, + completion: @escaping (Result) -> Void) + func useStorageEmulator(app: PigeonStorageFirebaseApp, host: String, port: Int64, + completion: @escaping (Result) -> Void) + func referenceDelete(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + completion: @escaping (Result) -> Void) + func referenceGetDownloadURL(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + completion: @escaping (Result) -> Void) + func referenceGetMetaData(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + completion: @escaping (Result) -> Void) + func referenceList(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + options: PigeonListOptions, + completion: @escaping (Result) -> Void) + func referenceListAll(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + completion: @escaping (Result) -> Void) + func referenceGetData(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + maxSize: Int64, + completion: @escaping (Result) -> Void) + func referencePutData(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + data: FlutterStandardTypedData, settableMetaData: PigeonSettableMetadata, + handle: Int64, completion: @escaping (Result) -> Void) + func referencePutString(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + data: String, format: Int64, settableMetaData: PigeonSettableMetadata, + handle: Int64, completion: @escaping (Result) -> Void) + func referencePutFile(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + filePath: String, settableMetaData: PigeonSettableMetadata?, handle: Int64, + completion: @escaping (Result) -> Void) + func referenceDownloadFile(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + filePath: String, handle: Int64, + completion: @escaping (Result) -> Void) + func referenceUpdateMetadata(app: PigeonStorageFirebaseApp, reference: PigeonStorageReference, + metadata: PigeonSettableMetadata, + completion: @escaping (Result) -> Void) + func taskPause(app: PigeonStorageFirebaseApp, handle: Int64, + completion: @escaping (Result<[String: Any], Error>) -> Void) + func taskResume(app: PigeonStorageFirebaseApp, handle: Int64, + completion: @escaping (Result<[String: Any], Error>) -> Void) + func taskCancel(app: PigeonStorageFirebaseApp, handle: Int64, + completion: @escaping (Result<[String: Any], Error>) -> Void) +} + +/// Generated setup class from Pigeon to handle messages through the `binaryMessenger`. +class FirebaseStorageHostApiSetup { + /// The codec used by FirebaseStorageHostApi. + static var codec: FlutterStandardMessageCodec { FirebaseStorageHostApiCodec.shared } + /// Sets up an instance of `FirebaseStorageHostApi` to handle messages through the + /// `binaryMessenger`. + static func setUp(binaryMessenger: FlutterBinaryMessenger, api: FirebaseStorageHostApi?) { + let getReferencebyPathChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.getReferencebyPath", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + getReferencebyPathChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let pathArg = args[1] as! String + let bucketArg: String? = nilOrValue(args[2]) + api.getReferencebyPath(app: appArg, path: pathArg, bucket: bucketArg) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + getReferencebyPathChannel.setMessageHandler(nil) + } + let setMaxOperationRetryTimeChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxOperationRetryTime", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + setMaxOperationRetryTimeChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let timeArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + api.setMaxOperationRetryTime(app: appArg, time: timeArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + setMaxOperationRetryTimeChannel.setMessageHandler(nil) + } + let setMaxUploadRetryTimeChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxUploadRetryTime", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + setMaxUploadRetryTimeChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let timeArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + api.setMaxUploadRetryTime(app: appArg, time: timeArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + setMaxUploadRetryTimeChannel.setMessageHandler(nil) + } + let setMaxDownloadRetryTimeChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.setMaxDownloadRetryTime", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + setMaxDownloadRetryTimeChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let timeArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + api.setMaxDownloadRetryTime(app: appArg, time: timeArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + setMaxDownloadRetryTimeChannel.setMessageHandler(nil) + } + let useStorageEmulatorChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.useStorageEmulator", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + useStorageEmulatorChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let hostArg = args[1] as! String + let portArg = args[2] is Int64 ? args[2] as! Int64 : Int64(args[2] as! Int32) + api.useStorageEmulator(app: appArg, host: hostArg, port: portArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + useStorageEmulatorChannel.setMessageHandler(nil) + } + let referenceDeleteChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDelete", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referenceDeleteChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + api.referenceDelete(app: appArg, reference: referenceArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referenceDeleteChannel.setMessageHandler(nil) + } + let referenceGetDownloadURLChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetDownloadURL", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referenceGetDownloadURLChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + api.referenceGetDownloadURL(app: appArg, reference: referenceArg) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referenceGetDownloadURLChannel.setMessageHandler(nil) + } + let referenceGetMetaDataChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetMetaData", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referenceGetMetaDataChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + api.referenceGetMetaData(app: appArg, reference: referenceArg) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referenceGetMetaDataChannel.setMessageHandler(nil) + } + let referenceListChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceList", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referenceListChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + let optionsArg = args[2] as! PigeonListOptions + api.referenceList(app: appArg, reference: referenceArg, options: optionsArg) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referenceListChannel.setMessageHandler(nil) + } + let referenceListAllChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceListAll", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referenceListAllChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + api.referenceListAll(app: appArg, reference: referenceArg) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referenceListAllChannel.setMessageHandler(nil) + } + let referenceGetDataChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceGetData", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referenceGetDataChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + let maxSizeArg = args[2] is Int64 ? args[2] as! Int64 : Int64(args[2] as! Int32) + api.referenceGetData(app: appArg, reference: referenceArg, maxSize: maxSizeArg) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referenceGetDataChannel.setMessageHandler(nil) + } + let referencePutDataChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutData", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referencePutDataChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + let dataArg = args[2] as! FlutterStandardTypedData + let settableMetaDataArg = args[3] as! PigeonSettableMetadata + let handleArg = args[4] is Int64 ? args[4] as! Int64 : Int64(args[4] as! Int32) + api.referencePutData( + app: appArg, + reference: referenceArg, + data: dataArg, + settableMetaData: settableMetaDataArg, + handle: handleArg + ) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referencePutDataChannel.setMessageHandler(nil) + } + let referencePutStringChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutString", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referencePutStringChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + let dataArg = args[2] as! String + let formatArg = args[3] is Int64 ? args[3] as! Int64 : Int64(args[3] as! Int32) + let settableMetaDataArg = args[4] as! PigeonSettableMetadata + let handleArg = args[5] is Int64 ? args[5] as! Int64 : Int64(args[5] as! Int32) + api.referencePutString( + app: appArg, + reference: referenceArg, + data: dataArg, + format: formatArg, + settableMetaData: settableMetaDataArg, + handle: handleArg + ) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referencePutStringChannel.setMessageHandler(nil) + } + let referencePutFileChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referencePutFile", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referencePutFileChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + let filePathArg = args[2] as! String + let settableMetaDataArg: PigeonSettableMetadata? = nilOrValue(args[3]) + let handleArg = args[4] is Int64 ? args[4] as! Int64 : Int64(args[4] as! Int32) + api.referencePutFile( + app: appArg, + reference: referenceArg, + filePath: filePathArg, + settableMetaData: settableMetaDataArg, + handle: handleArg + ) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referencePutFileChannel.setMessageHandler(nil) + } + let referenceDownloadFileChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceDownloadFile", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referenceDownloadFileChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + let filePathArg = args[2] as! String + let handleArg = args[3] is Int64 ? args[3] as! Int64 : Int64(args[3] as! Int32) + api.referenceDownloadFile( + app: appArg, + reference: referenceArg, + filePath: filePathArg, + handle: handleArg + ) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referenceDownloadFileChannel.setMessageHandler(nil) + } + let referenceUpdateMetadataChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.referenceUpdateMetadata", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + referenceUpdateMetadataChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let referenceArg = args[1] as! PigeonStorageReference + let metadataArg = args[2] as! PigeonSettableMetadata + api + .referenceUpdateMetadata(app: appArg, reference: referenceArg, + metadata: metadataArg) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + referenceUpdateMetadataChannel.setMessageHandler(nil) + } + let taskPauseChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskPause", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + taskPauseChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let handleArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + api.taskPause(app: appArg, handle: handleArg) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + taskPauseChannel.setMessageHandler(nil) + } + let taskResumeChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskResume", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + taskResumeChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let handleArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + api.taskResume(app: appArg, handle: handleArg) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + taskResumeChannel.setMessageHandler(nil) + } + let taskCancelChannel = FlutterBasicMessageChannel( + name: "dev.flutter.pigeon.firebase_storage_platform_interface.FirebaseStorageHostApi.taskCancel", + binaryMessenger: binaryMessenger, + codec: codec + ) + if let api { + taskCancelChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let appArg = args[0] as! PigeonStorageFirebaseApp + let handleArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + api.taskCancel(app: appArg, handle: handleArg) { result in + switch result { + case let .success(res): + reply(wrapResult(res)) + case let .failure(error): + reply(wrapError(error)) + } + } + } + } else { + taskCancelChannel.setMessageHandler(nil) + } + } +} diff --git a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/TaskStateChannelStreamHandler.swift b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/TaskStateChannelStreamHandler.swift new file mode 100644 index 000000000000..9cc69b046a25 --- /dev/null +++ b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/TaskStateChannelStreamHandler.swift @@ -0,0 +1,160 @@ +// Copyright 2025 The Chromium Authors. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import FirebaseStorage +import Foundation + +#if os(iOS) + import Flutter +#elseif os(macOS) + import FlutterMacOS +#endif + +final class TaskStateChannelStreamHandler: NSObject, FlutterStreamHandler { + private let task: StorageObservableTask + private let storage: Storage + private let identifier: String + + private var successHandle: String? + private var failureHandle: String? + private var pausedHandle: String? + private var progressHandle: String? + + init(task: StorageObservableTask, storage: Storage, identifier: String) { + self.task = task + self.storage = storage + self.identifier = identifier + } + + func onListen(withArguments arguments: Any?, + eventSink events: @escaping FlutterEventSink) -> FlutterError? { + successHandle = task.observe(.success) { snapshot in + events([ + "taskState": 2, // success + "appName": self.storage.app.name, + "snapshot": self.parseTaskSnapshot(snapshot), + ]) + self.cleanupObservers() + } + failureHandle = task.observe(.failure) { snapshot in + let err = snapshot.error as NSError? + let errorDict: [String: Any] = self.errorDict(err) + events([ + "taskState": 4, // error (including cancellations as errors per platform contract) + "appName": self.storage.app.name, + "error": errorDict, + ]) + self.cleanupObservers() + } + pausedHandle = task.observe(.pause) { snapshot in + events([ + "taskState": 0, // paused + "appName": self.storage.app.name, + "snapshot": self.parseTaskSnapshot(snapshot), + ]) + } + progressHandle = task.observe(.progress) { snapshot in + events([ + "taskState": 1, // running + "appName": self.storage.app.name, + "snapshot": self.parseTaskSnapshot(snapshot), + ]) + } + return nil + } + + func onCancel(withArguments arguments: Any?) -> FlutterError? { + cleanupObservers() + return nil + } + + private func cleanupObservers() { + if let h = successHandle { task.removeObserver(withHandle: h) } + if let h = failureHandle { task.removeObserver(withHandle: h) } + if let h = pausedHandle { task.removeObserver(withHandle: h) } + if let h = progressHandle { task.removeObserver(withHandle: h) } + successHandle = nil + failureHandle = nil + pausedHandle = nil + progressHandle = nil + } + + private func parseTaskSnapshot(_ snapshot: StorageTaskSnapshot) -> [String: Any] { + var out: [String: Any] = [:] + out["path"] = snapshot.reference.fullPath + if let md = snapshot.metadata { + out["metadata"] = metaToDict(md) + } + if let progress = snapshot.progress { + out["bytesTransferred"] = progress.completedUnitCount + out["totalBytes"] = progress.totalUnitCount + } else { + out["bytesTransferred"] = 0 + out["totalBytes"] = 0 + } + return out + } + + private func errorDict(_ error: NSError?) -> [String: Any] { + guard let error else { + return [ + "code": "unknown", + "message": "An unknown error occurred", + ] + } + let code: String + if error.domain == StorageErrorDomain, + let storageCode = StorageErrorCode(rawValue: error.code) { + switch storageCode { + case .objectNotFound: code = "object-not-found" + case .bucketNotFound: code = "bucket-not-found" + case .projectNotFound: code = "project-not-found" + case .quotaExceeded: code = "quota-exceeded" + case .unauthenticated: code = "unauthenticated" + case .unauthorized: code = "unauthorized" + case .retryLimitExceeded: code = "retry-limit-exceeded" + case .cancelled: code = "canceled" + case .downloadSizeExceeded: code = "download-size-exceeded" + @unknown default: code = "unknown" + } + } else if error.domain == NSURLErrorDomain, error.code == NSURLErrorCancelled { + code = "canceled" + } else { + code = "unknown" + } + return [ + "code": code, + "message": standardMessage(for: code) ?? error.localizedDescription, + ] + } + + private func standardMessage(for code: String) -> String? { + switch code { + case "object-not-found": return "No object exists at the desired reference." + case "unauthorized": return "User is not authorized to perform the desired action." + case "canceled": return "The operation was canceled." + default: return nil + } + } + + private func metaToDict(_ md: StorageMetadata) -> [String: Any] { + var out: [String: Any] = [:] + out["name"] = md.name + out["bucket"] = md.bucket + out["generation"] = String(md.generation) + out["metadataGeneration"] = String(md.metageneration) + out["fullPath"] = md.path + out["size"] = md.size + out["creationTimeMillis"] = Int((md.timeCreated?.timeIntervalSince1970 ?? 0) * 1000) + out["updatedTimeMillis"] = Int((md.updated?.timeIntervalSince1970 ?? 0) * 1000) + if let v = md.md5Hash { out["md5Hash"] = v } + if let v = md.cacheControl { out["cacheControl"] = v } + if let v = md.contentDisposition { out["contentDisposition"] = v } + if let v = md.contentEncoding { out["contentEncoding"] = v } + if let v = md.contentLanguage { out["contentLanguage"] = v } + if let v = md.contentType { out["contentType"] = v } + out["customMetadata"] = md.customMetadata ?? [:] + return out + } +} diff --git a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/firebase_storage_messages.g.m b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/firebase_storage_messages.g.m deleted file mode 100644 index 975e4e0a7406..000000000000 --- a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/firebase_storage_messages.g.m +++ /dev/null @@ -1,866 +0,0 @@ -// Copyright 2023, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -// Autogenerated from Pigeon (v11.0.1), do not edit directly. -// See also: https://pub.dev/packages/pigeon - -#import "firebase_storage_messages.g.h" - -#if TARGET_OS_OSX -#import -#else -#import -#endif - -#if !__has_feature(objc_arc) -#error File requires ARC to be enabled. -#endif - -/// The type of operation that generated the action code from calling -/// [TaskState]. -@implementation PigeonStorageTaskStateBox -- (instancetype)initWithValue:(PigeonStorageTaskState)value { - self = [super init]; - if (self) { - _value = value; - } - return self; -} -@end - -static NSArray *wrapResult(id result, FlutterError *error) { - if (error) { - return @[ - error.code ?: [NSNull null], error.message ?: [NSNull null], error.details ?: [NSNull null] - ]; - } - return @[ result ?: [NSNull null] ]; -} -static id GetNullableObjectAtIndex(NSArray *array, NSInteger key) { - id result = array[key]; - return (result == [NSNull null]) ? nil : result; -} - -@interface PigeonStorageFirebaseApp () -+ (PigeonStorageFirebaseApp *)fromList:(NSArray *)list; -+ (nullable PigeonStorageFirebaseApp *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@interface PigeonStorageReference () -+ (PigeonStorageReference *)fromList:(NSArray *)list; -+ (nullable PigeonStorageReference *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@interface PigeonFullMetaData () -+ (PigeonFullMetaData *)fromList:(NSArray *)list; -+ (nullable PigeonFullMetaData *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@interface PigeonListOptions () -+ (PigeonListOptions *)fromList:(NSArray *)list; -+ (nullable PigeonListOptions *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@interface PigeonSettableMetadata () -+ (PigeonSettableMetadata *)fromList:(NSArray *)list; -+ (nullable PigeonSettableMetadata *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@interface PigeonListResult () -+ (PigeonListResult *)fromList:(NSArray *)list; -+ (nullable PigeonListResult *)nullableFromList:(NSArray *)list; -- (NSArray *)toList; -@end - -@implementation PigeonStorageFirebaseApp -+ (instancetype)makeWithAppName:(NSString *)appName - tenantId:(nullable NSString *)tenantId - bucket:(NSString *)bucket { - PigeonStorageFirebaseApp *pigeonResult = [[PigeonStorageFirebaseApp alloc] init]; - pigeonResult.appName = appName; - pigeonResult.tenantId = tenantId; - pigeonResult.bucket = bucket; - return pigeonResult; -} -+ (PigeonStorageFirebaseApp *)fromList:(NSArray *)list { - PigeonStorageFirebaseApp *pigeonResult = [[PigeonStorageFirebaseApp alloc] init]; - pigeonResult.appName = GetNullableObjectAtIndex(list, 0); - NSAssert(pigeonResult.appName != nil, @""); - pigeonResult.tenantId = GetNullableObjectAtIndex(list, 1); - pigeonResult.bucket = GetNullableObjectAtIndex(list, 2); - NSAssert(pigeonResult.bucket != nil, @""); - return pigeonResult; -} -+ (nullable PigeonStorageFirebaseApp *)nullableFromList:(NSArray *)list { - return (list) ? [PigeonStorageFirebaseApp fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - (self.appName ?: [NSNull null]), - (self.tenantId ?: [NSNull null]), - (self.bucket ?: [NSNull null]), - ]; -} -@end - -@implementation PigeonStorageReference -+ (instancetype)makeWithBucket:(NSString *)bucket - fullPath:(NSString *)fullPath - name:(NSString *)name { - PigeonStorageReference *pigeonResult = [[PigeonStorageReference alloc] init]; - pigeonResult.bucket = bucket; - pigeonResult.fullPath = fullPath; - pigeonResult.name = name; - return pigeonResult; -} -+ (PigeonStorageReference *)fromList:(NSArray *)list { - PigeonStorageReference *pigeonResult = [[PigeonStorageReference alloc] init]; - pigeonResult.bucket = GetNullableObjectAtIndex(list, 0); - NSAssert(pigeonResult.bucket != nil, @""); - pigeonResult.fullPath = GetNullableObjectAtIndex(list, 1); - NSAssert(pigeonResult.fullPath != nil, @""); - pigeonResult.name = GetNullableObjectAtIndex(list, 2); - NSAssert(pigeonResult.name != nil, @""); - return pigeonResult; -} -+ (nullable PigeonStorageReference *)nullableFromList:(NSArray *)list { - return (list) ? [PigeonStorageReference fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - (self.bucket ?: [NSNull null]), - (self.fullPath ?: [NSNull null]), - (self.name ?: [NSNull null]), - ]; -} -@end - -@implementation PigeonFullMetaData -+ (instancetype)makeWithMetadata:(nullable NSDictionary *)metadata { - PigeonFullMetaData *pigeonResult = [[PigeonFullMetaData alloc] init]; - pigeonResult.metadata = metadata; - return pigeonResult; -} -+ (PigeonFullMetaData *)fromList:(NSArray *)list { - PigeonFullMetaData *pigeonResult = [[PigeonFullMetaData alloc] init]; - pigeonResult.metadata = GetNullableObjectAtIndex(list, 0); - return pigeonResult; -} -+ (nullable PigeonFullMetaData *)nullableFromList:(NSArray *)list { - return (list) ? [PigeonFullMetaData fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - (self.metadata ?: [NSNull null]), - ]; -} -@end - -@implementation PigeonListOptions -+ (instancetype)makeWithMaxResults:(NSNumber *)maxResults pageToken:(nullable NSString *)pageToken { - PigeonListOptions *pigeonResult = [[PigeonListOptions alloc] init]; - pigeonResult.maxResults = maxResults; - pigeonResult.pageToken = pageToken; - return pigeonResult; -} -+ (PigeonListOptions *)fromList:(NSArray *)list { - PigeonListOptions *pigeonResult = [[PigeonListOptions alloc] init]; - pigeonResult.maxResults = GetNullableObjectAtIndex(list, 0); - NSAssert(pigeonResult.maxResults != nil, @""); - pigeonResult.pageToken = GetNullableObjectAtIndex(list, 1); - return pigeonResult; -} -+ (nullable PigeonListOptions *)nullableFromList:(NSArray *)list { - return (list) ? [PigeonListOptions fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - (self.maxResults ?: [NSNull null]), - (self.pageToken ?: [NSNull null]), - ]; -} -@end - -@implementation PigeonSettableMetadata -+ (instancetype)makeWithCacheControl:(nullable NSString *)cacheControl - contentDisposition:(nullable NSString *)contentDisposition - contentEncoding:(nullable NSString *)contentEncoding - contentLanguage:(nullable NSString *)contentLanguage - contentType:(nullable NSString *)contentType - customMetadata: - (nullable NSDictionary *)customMetadata { - PigeonSettableMetadata *pigeonResult = [[PigeonSettableMetadata alloc] init]; - pigeonResult.cacheControl = cacheControl; - pigeonResult.contentDisposition = contentDisposition; - pigeonResult.contentEncoding = contentEncoding; - pigeonResult.contentLanguage = contentLanguage; - pigeonResult.contentType = contentType; - pigeonResult.customMetadata = customMetadata; - return pigeonResult; -} -+ (PigeonSettableMetadata *)fromList:(NSArray *)list { - PigeonSettableMetadata *pigeonResult = [[PigeonSettableMetadata alloc] init]; - pigeonResult.cacheControl = GetNullableObjectAtIndex(list, 0); - pigeonResult.contentDisposition = GetNullableObjectAtIndex(list, 1); - pigeonResult.contentEncoding = GetNullableObjectAtIndex(list, 2); - pigeonResult.contentLanguage = GetNullableObjectAtIndex(list, 3); - pigeonResult.contentType = GetNullableObjectAtIndex(list, 4); - pigeonResult.customMetadata = GetNullableObjectAtIndex(list, 5); - return pigeonResult; -} -+ (nullable PigeonSettableMetadata *)nullableFromList:(NSArray *)list { - return (list) ? [PigeonSettableMetadata fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - (self.cacheControl ?: [NSNull null]), - (self.contentDisposition ?: [NSNull null]), - (self.contentEncoding ?: [NSNull null]), - (self.contentLanguage ?: [NSNull null]), - (self.contentType ?: [NSNull null]), - (self.customMetadata ?: [NSNull null]), - ]; -} -@end - -@implementation PigeonListResult -+ (instancetype)makeWithItems:(NSArray *)items - pageToken:(nullable NSString *)pageToken - prefixs:(NSArray *)prefixs { - PigeonListResult *pigeonResult = [[PigeonListResult alloc] init]; - pigeonResult.items = items; - pigeonResult.pageToken = pageToken; - pigeonResult.prefixs = prefixs; - return pigeonResult; -} -+ (PigeonListResult *)fromList:(NSArray *)list { - PigeonListResult *pigeonResult = [[PigeonListResult alloc] init]; - pigeonResult.items = GetNullableObjectAtIndex(list, 0); - NSAssert(pigeonResult.items != nil, @""); - pigeonResult.pageToken = GetNullableObjectAtIndex(list, 1); - pigeonResult.prefixs = GetNullableObjectAtIndex(list, 2); - NSAssert(pigeonResult.prefixs != nil, @""); - return pigeonResult; -} -+ (nullable PigeonListResult *)nullableFromList:(NSArray *)list { - return (list) ? [PigeonListResult fromList:list] : nil; -} -- (NSArray *)toList { - return @[ - (self.items ?: [NSNull null]), - (self.pageToken ?: [NSNull null]), - (self.prefixs ?: [NSNull null]), - ]; -} -@end - -@interface FirebaseStorageHostApiCodecReader : FlutterStandardReader -@end -@implementation FirebaseStorageHostApiCodecReader -- (nullable id)readValueOfType:(UInt8)type { - switch (type) { - case 128: - return [PigeonFullMetaData fromList:[self readValue]]; - case 129: - return [PigeonListOptions fromList:[self readValue]]; - case 130: - return [PigeonListResult fromList:[self readValue]]; - case 131: - return [PigeonSettableMetadata fromList:[self readValue]]; - case 132: - return [PigeonStorageFirebaseApp fromList:[self readValue]]; - case 133: - return [PigeonStorageReference fromList:[self readValue]]; - default: - return [super readValueOfType:type]; - } -} -@end - -@interface FirebaseStorageHostApiCodecWriter : FlutterStandardWriter -@end -@implementation FirebaseStorageHostApiCodecWriter -- (void)writeValue:(id)value { - if ([value isKindOfClass:[PigeonFullMetaData class]]) { - [self writeByte:128]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[PigeonListOptions class]]) { - [self writeByte:129]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[PigeonListResult class]]) { - [self writeByte:130]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[PigeonSettableMetadata class]]) { - [self writeByte:131]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[PigeonStorageFirebaseApp class]]) { - [self writeByte:132]; - [self writeValue:[value toList]]; - } else if ([value isKindOfClass:[PigeonStorageReference class]]) { - [self writeByte:133]; - [self writeValue:[value toList]]; - } else { - [super writeValue:value]; - } -} -@end - -@interface FirebaseStorageHostApiCodecReaderWriter : FlutterStandardReaderWriter -@end -@implementation FirebaseStorageHostApiCodecReaderWriter -- (FlutterStandardWriter *)writerWithData:(NSMutableData *)data { - return [[FirebaseStorageHostApiCodecWriter alloc] initWithData:data]; -} -- (FlutterStandardReader *)readerWithData:(NSData *)data { - return [[FirebaseStorageHostApiCodecReader alloc] initWithData:data]; -} -@end - -NSObject *FirebaseStorageHostApiGetCodec(void) { - static FlutterStandardMessageCodec *sSharedObject = nil; - static dispatch_once_t sPred = 0; - dispatch_once(&sPred, ^{ - FirebaseStorageHostApiCodecReaderWriter *readerWriter = - [[FirebaseStorageHostApiCodecReaderWriter alloc] init]; - sSharedObject = [FlutterStandardMessageCodec codecWithReaderWriter:readerWriter]; - }); - return sSharedObject; -} - -void FirebaseStorageHostApiSetup(id binaryMessenger, - NSObject *api) { - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.getReferencebyPath" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(getReferencebyPathApp:path:bucket:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(getReferencebyPathApp:path:bucket:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - NSString *arg_path = GetNullableObjectAtIndex(args, 1); - NSString *arg_bucket = GetNullableObjectAtIndex(args, 2); - [api getReferencebyPathApp:arg_app - path:arg_path - bucket:arg_bucket - completion:^(PigeonStorageReference *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.setMaxOperationRetryTime" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(setMaxOperationRetryTimeApp:time:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(setMaxOperationRetryTimeApp:time:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_time = GetNullableObjectAtIndex(args, 1); - [api setMaxOperationRetryTimeApp:arg_app - time:arg_time - completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.setMaxUploadRetryTime" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(setMaxUploadRetryTimeApp:time:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(setMaxUploadRetryTimeApp:time:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_time = GetNullableObjectAtIndex(args, 1); - [api setMaxUploadRetryTimeApp:arg_app - time:arg_time - completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.setMaxDownloadRetryTime" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(setMaxDownloadRetryTimeApp:time:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(setMaxDownloadRetryTimeApp:time:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_time = GetNullableObjectAtIndex(args, 1); - [api setMaxDownloadRetryTimeApp:arg_app - time:arg_time - completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.useStorageEmulator" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(useStorageEmulatorApp:host:port:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(useStorageEmulatorApp:host:port:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - NSString *arg_host = GetNullableObjectAtIndex(args, 1); - NSNumber *arg_port = GetNullableObjectAtIndex(args, 2); - [api useStorageEmulatorApp:arg_app - host:arg_host - port:arg_port - completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referenceDelete" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(referenceDeleteApp:reference:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referenceDeleteApp:reference:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - [api referenceDeleteApp:arg_app - reference:arg_reference - completion:^(FlutterError *_Nullable error) { - callback(wrapResult(nil, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referenceGetDownloadURL" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(referenceGetDownloadURLApp: - reference:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referenceGetDownloadURLApp:reference:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - [api referenceGetDownloadURLApp:arg_app - reference:arg_reference - completion:^(NSString *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referenceGetMetaData" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(referenceGetMetaDataApp:reference:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referenceGetMetaDataApp:reference:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - [api referenceGetMetaDataApp:arg_app - reference:arg_reference - completion:^(PigeonFullMetaData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referenceList" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(referenceListApp:reference:options:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referenceListApp:reference:options:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - PigeonListOptions *arg_options = GetNullableObjectAtIndex(args, 2); - [api referenceListApp:arg_app - reference:arg_reference - options:arg_options - completion:^(PigeonListResult *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referenceListAll" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(referenceListAllApp:reference:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referenceListAllApp:reference:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - [api referenceListAllApp:arg_app - reference:arg_reference - completion:^(PigeonListResult *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referenceGetData" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(referenceGetDataApp: - reference:maxSize:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referenceGetDataApp:reference:maxSize:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - NSNumber *arg_maxSize = GetNullableObjectAtIndex(args, 2); - [api referenceGetDataApp:arg_app - reference:arg_reference - maxSize:arg_maxSize - completion:^(FlutterStandardTypedData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referencePutData" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert( - [api respondsToSelector:@selector - (referencePutDataApp:reference:data:settableMetaData:handle:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referencePutDataApp:reference:data:settableMetaData:handle:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - FlutterStandardTypedData *arg_data = GetNullableObjectAtIndex(args, 2); - PigeonSettableMetadata *arg_settableMetaData = GetNullableObjectAtIndex(args, 3); - NSNumber *arg_handle = GetNullableObjectAtIndex(args, 4); - [api referencePutDataApp:arg_app - reference:arg_reference - data:arg_data - settableMetaData:arg_settableMetaData - handle:arg_handle - completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referencePutString" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector - (referencePutStringApp: - reference:data:format:settableMetaData:handle:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referencePutStringApp:reference:data:format:settableMetaData:handle:" - @"completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - NSString *arg_data = GetNullableObjectAtIndex(args, 2); - NSNumber *arg_format = GetNullableObjectAtIndex(args, 3); - PigeonSettableMetadata *arg_settableMetaData = GetNullableObjectAtIndex(args, 4); - NSNumber *arg_handle = GetNullableObjectAtIndex(args, 5); - [api referencePutStringApp:arg_app - reference:arg_reference - data:arg_data - format:arg_format - settableMetaData:arg_settableMetaData - handle:arg_handle - completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referencePutFile" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert( - [api respondsToSelector:@selector - (referencePutFileApp:reference:filePath:settableMetaData:handle:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referencePutFileApp:reference:filePath:settableMetaData:handle:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - NSString *arg_filePath = GetNullableObjectAtIndex(args, 2); - PigeonSettableMetadata *arg_settableMetaData = GetNullableObjectAtIndex(args, 3); - NSNumber *arg_handle = GetNullableObjectAtIndex(args, 4); - [api referencePutFileApp:arg_app - reference:arg_reference - filePath:arg_filePath - settableMetaData:arg_settableMetaData - handle:arg_handle - completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referenceDownloadFile" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector - (referenceDownloadFileApp:reference:filePath:handle:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referenceDownloadFileApp:reference:filePath:handle:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - NSString *arg_filePath = GetNullableObjectAtIndex(args, 2); - NSNumber *arg_handle = GetNullableObjectAtIndex(args, 3); - [api referenceDownloadFileApp:arg_app - reference:arg_reference - filePath:arg_filePath - handle:arg_handle - completion:^(NSString *_Nullable output, FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.referenceUpdateMetadata" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(referenceUpdateMetadataApp: - reference:metadata:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(referenceUpdateMetadataApp:reference:metadata:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - PigeonStorageReference *arg_reference = GetNullableObjectAtIndex(args, 1); - PigeonSettableMetadata *arg_metadata = GetNullableObjectAtIndex(args, 2); - [api referenceUpdateMetadataApp:arg_app - reference:arg_reference - metadata:arg_metadata - completion:^(PigeonFullMetaData *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.taskPause" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(taskPauseApp:handle:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(taskPauseApp:handle:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_handle = GetNullableObjectAtIndex(args, 1); - [api taskPauseApp:arg_app - handle:arg_handle - completion:^(NSDictionary *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.taskResume" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(taskResumeApp:handle:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(taskResumeApp:handle:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_handle = GetNullableObjectAtIndex(args, 1); - [api taskResumeApp:arg_app - handle:arg_handle - completion:^(NSDictionary *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } - { - FlutterBasicMessageChannel *channel = [[FlutterBasicMessageChannel alloc] - initWithName:@"dev.flutter.pigeon.firebase_storage_platform_interface." - @"FirebaseStorageHostApi.taskCancel" - binaryMessenger:binaryMessenger - codec:FirebaseStorageHostApiGetCodec()]; - if (api) { - NSCAssert([api respondsToSelector:@selector(taskCancelApp:handle:completion:)], - @"FirebaseStorageHostApi api (%@) doesn't respond to " - @"@selector(taskCancelApp:handle:completion:)", - api); - [channel setMessageHandler:^(id _Nullable message, FlutterReply callback) { - NSArray *args = message; - PigeonStorageFirebaseApp *arg_app = GetNullableObjectAtIndex(args, 0); - NSNumber *arg_handle = GetNullableObjectAtIndex(args, 1); - [api taskCancelApp:arg_app - handle:arg_handle - completion:^(NSDictionary *_Nullable output, - FlutterError *_Nullable error) { - callback(wrapResult(output, error)); - }]; - }]; - } else { - [channel setMessageHandler:nil]; - } - } -} diff --git a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/include/FLTFirebaseStoragePlugin.h b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/include/FLTFirebaseStoragePlugin.h deleted file mode 100644 index b1d616329395..000000000000 --- a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/include/FLTFirebaseStoragePlugin.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. -#import - -#if TARGET_OS_OSX -// Forward declarations of Firebase Storage type -@class FIRStorageTaskSnapshot; -#import -#else -#import -@import FirebaseStorage; -#endif - -#import -#if __has_include() -#import -#else -#import -#endif -#import "firebase_storage_messages.g.h" - -@interface FLTFirebaseStoragePlugin - : FLTFirebasePlugin - -+ (NSDictionary *)parseTaskSnapshot:(FIRStorageTaskSnapshot *)snapshot; -+ (NSDictionary *)NSDictionaryFromNSError:(NSError *)error; -- (void)cleanUpTask:(NSString *)channelName handle:(NSNumber *)handle; -@end diff --git a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/include/FLTTaskStateChannelStreamHandler.h b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/include/FLTTaskStateChannelStreamHandler.h deleted file mode 100644 index 681a0964d024..000000000000 --- a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/include/FLTTaskStateChannelStreamHandler.h +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2023 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#import - -#if TARGET_OS_OSX -// Forward declarations of Firebase Storage type -@class FIRStorageObservableTask; -#import -#else -#import -@import FirebaseStorage; -#endif - -#import -#import "FLTFirebaseStoragePlugin.h" - -NS_ASSUME_NONNULL_BEGIN - -@interface FLTTaskStateChannelStreamHandler : NSObject -- (instancetype)initWithTask:(FIRStorageObservableTask *)task - storagePlugin:(FLTFirebaseStoragePlugin *)storagePlugin - channelName:(NSString *)channelName - handle:(NSNumber *)handle; - -@end - -NS_ASSUME_NONNULL_END diff --git a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/include/firebase_storage_messages.g.h b/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/include/firebase_storage_messages.g.h deleted file mode 100644 index 451ee2320ce8..000000000000 --- a/packages/firebase_storage/firebase_storage/ios/firebase_storage/Sources/firebase_storage/include/firebase_storage_messages.g.h +++ /dev/null @@ -1,220 +0,0 @@ -// Copyright 2023, the Chromium project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. -// Autogenerated from Pigeon (v11.0.1), do not edit directly. -// See also: https://pub.dev/packages/pigeon - -#import - -@protocol FlutterBinaryMessenger; -@protocol FlutterMessageCodec; -@class FlutterError; -@class FlutterStandardTypedData; - -NS_ASSUME_NONNULL_BEGIN - -/// The type of operation that generated the action code from calling -/// [TaskState]. -typedef NS_ENUM(NSUInteger, PigeonStorageTaskState) { - /// Indicates the task has been paused by the user. - PigeonStorageTaskStatePaused = 0, - /// Indicates the task is currently in-progress. - PigeonStorageTaskStateRunning = 1, - /// Indicates the task has successfully completed. - PigeonStorageTaskStateSuccess = 2, - /// Indicates the task was canceled. - PigeonStorageTaskStateCanceled = 3, - /// Indicates the task failed with an error. - PigeonStorageTaskStateError = 4, -}; - -/// Wrapper for PigeonStorageTaskState to allow for nullability. -@interface PigeonStorageTaskStateBox : NSObject -@property(nonatomic, assign) PigeonStorageTaskState value; -- (instancetype)initWithValue:(PigeonStorageTaskState)value; -@end - -@class PigeonStorageFirebaseApp; -@class PigeonStorageReference; -@class PigeonFullMetaData; -@class PigeonListOptions; -@class PigeonSettableMetadata; -@class PigeonListResult; - -@interface PigeonStorageFirebaseApp : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithAppName:(NSString *)appName - tenantId:(nullable NSString *)tenantId - bucket:(NSString *)bucket; -@property(nonatomic, copy) NSString *appName; -@property(nonatomic, copy, nullable) NSString *tenantId; -@property(nonatomic, copy) NSString *bucket; -@end - -@interface PigeonStorageReference : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithBucket:(NSString *)bucket - fullPath:(NSString *)fullPath - name:(NSString *)name; -@property(nonatomic, copy) NSString *bucket; -@property(nonatomic, copy) NSString *fullPath; -@property(nonatomic, copy) NSString *name; -@end - -@interface PigeonFullMetaData : NSObject -+ (instancetype)makeWithMetadata:(nullable NSDictionary *)metadata; -@property(nonatomic, strong, nullable) NSDictionary *metadata; -@end - -@interface PigeonListOptions : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithMaxResults:(NSNumber *)maxResults pageToken:(nullable NSString *)pageToken; -/// If set, limits the total number of `prefixes` and `items` to return. -/// -/// The default and maximum maxResults is 1000. -@property(nonatomic, strong) NSNumber *maxResults; -/// The nextPageToken from a previous call to list(). -/// -/// If provided, listing is resumed from the previous position. -@property(nonatomic, copy, nullable) NSString *pageToken; -@end - -@interface PigeonSettableMetadata : NSObject -+ (instancetype)makeWithCacheControl:(nullable NSString *)cacheControl - contentDisposition:(nullable NSString *)contentDisposition - contentEncoding:(nullable NSString *)contentEncoding - contentLanguage:(nullable NSString *)contentLanguage - contentType:(nullable NSString *)contentType - customMetadata: - (nullable NSDictionary *)customMetadata; -/// Served as the 'Cache-Control' header on object download. -/// -/// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control. -@property(nonatomic, copy, nullable) NSString *cacheControl; -/// Served as the 'Content-Disposition' header on object download. -/// -/// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition. -@property(nonatomic, copy, nullable) NSString *contentDisposition; -/// Served as the 'Content-Encoding' header on object download. -/// -/// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding. -@property(nonatomic, copy, nullable) NSString *contentEncoding; -/// Served as the 'Content-Language' header on object download. -/// -/// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Language. -@property(nonatomic, copy, nullable) NSString *contentLanguage; -/// Served as the 'Content-Type' header on object download. -/// -/// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type. -@property(nonatomic, copy, nullable) NSString *contentType; -/// Additional user-defined custom metadata. -@property(nonatomic, strong, nullable) NSDictionary *customMetadata; -@end - -@interface PigeonListResult : NSObject -/// `init` unavailable to enforce nonnull fields, see the `make` class method. -- (instancetype)init NS_UNAVAILABLE; -+ (instancetype)makeWithItems:(NSArray *)items - pageToken:(nullable NSString *)pageToken - prefixs:(NSArray *)prefixs; -@property(nonatomic, strong) NSArray *items; -@property(nonatomic, copy, nullable) NSString *pageToken; -@property(nonatomic, strong) NSArray *prefixs; -@end - -/// The codec used by FirebaseStorageHostApi. -NSObject *FirebaseStorageHostApiGetCodec(void); - -@protocol FirebaseStorageHostApi -- (void)getReferencebyPathApp:(PigeonStorageFirebaseApp *)app - path:(NSString *)path - bucket:(nullable NSString *)bucket - completion:(void (^)(PigeonStorageReference *_Nullable, - FlutterError *_Nullable))completion; -- (void)setMaxOperationRetryTimeApp:(PigeonStorageFirebaseApp *)app - time:(NSNumber *)time - completion:(void (^)(FlutterError *_Nullable))completion; -- (void)setMaxUploadRetryTimeApp:(PigeonStorageFirebaseApp *)app - time:(NSNumber *)time - completion:(void (^)(FlutterError *_Nullable))completion; -- (void)setMaxDownloadRetryTimeApp:(PigeonStorageFirebaseApp *)app - time:(NSNumber *)time - completion:(void (^)(FlutterError *_Nullable))completion; -- (void)useStorageEmulatorApp:(PigeonStorageFirebaseApp *)app - host:(NSString *)host - port:(NSNumber *)port - completion:(void (^)(FlutterError *_Nullable))completion; -- (void)referenceDeleteApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - completion:(void (^)(FlutterError *_Nullable))completion; -- (void)referenceGetDownloadURLApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - completion: - (void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; -- (void)referenceGetMetaDataApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - completion:(void (^)(PigeonFullMetaData *_Nullable, - FlutterError *_Nullable))completion; -- (void)referenceListApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - options:(PigeonListOptions *)options - completion:(void (^)(PigeonListResult *_Nullable, FlutterError *_Nullable))completion; -- (void)referenceListAllApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - completion: - (void (^)(PigeonListResult *_Nullable, FlutterError *_Nullable))completion; -- (void)referenceGetDataApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - maxSize:(NSNumber *)maxSize - completion:(void (^)(FlutterStandardTypedData *_Nullable, - FlutterError *_Nullable))completion; -- (void)referencePutDataApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - data:(FlutterStandardTypedData *)data - settableMetaData:(PigeonSettableMetadata *)settableMetaData - handle:(NSNumber *)handle - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; -- (void)referencePutStringApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - data:(NSString *)data - format:(NSNumber *)format - settableMetaData:(PigeonSettableMetadata *)settableMetaData - handle:(NSNumber *)handle - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; -- (void)referencePutFileApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - filePath:(NSString *)filePath - settableMetaData:(nullable PigeonSettableMetadata *)settableMetaData - handle:(NSNumber *)handle - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; -- (void)referenceDownloadFileApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - filePath:(NSString *)filePath - handle:(NSNumber *)handle - completion:(void (^)(NSString *_Nullable, FlutterError *_Nullable))completion; -- (void)referenceUpdateMetadataApp:(PigeonStorageFirebaseApp *)app - reference:(PigeonStorageReference *)reference - metadata:(PigeonSettableMetadata *)metadata - completion:(void (^)(PigeonFullMetaData *_Nullable, - FlutterError *_Nullable))completion; -- (void)taskPauseApp:(PigeonStorageFirebaseApp *)app - handle:(NSNumber *)handle - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion; -- (void)taskResumeApp:(PigeonStorageFirebaseApp *)app - handle:(NSNumber *)handle - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion; -- (void)taskCancelApp:(PigeonStorageFirebaseApp *)app - handle:(NSNumber *)handle - completion:(void (^)(NSDictionary *_Nullable, - FlutterError *_Nullable))completion; -@end - -extern void FirebaseStorageHostApiSetup(id binaryMessenger, - NSObject *_Nullable api); - -NS_ASSUME_NONNULL_END diff --git a/packages/firebase_storage/firebase_storage/macos/firebase_storage.podspec b/packages/firebase_storage/firebase_storage/macos/firebase_storage.podspec index 744336dfc472..12c7a116a466 100755 --- a/packages/firebase_storage/firebase_storage/macos/firebase_storage.podspec +++ b/packages/firebase_storage/firebase_storage/macos/firebase_storage.podspec @@ -43,7 +43,7 @@ Pod::Spec.new do |s| s.authors = 'The Chromium Authors' s.source = { :path => '.' } - s.source_files = 'firebase_storage/Sources/firebase_storage/**/*.{h,m}' + s.source_files = 'firebase_storage/Sources/firebase_storage/**/*.{h,m,swift}' s.public_header_files = 'firebase_storage/Sources/firebase_storage/include/*.h' s.platform = :osx, '10.13' diff --git a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.m b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.m deleted file mode 120000 index 0d2def8bce9f..000000000000 --- a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.m +++ /dev/null @@ -1 +0,0 @@ -../../../../ios/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.m \ No newline at end of file diff --git a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.swift b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.swift new file mode 120000 index 000000000000..0a96b2bbf102 --- /dev/null +++ b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.swift @@ -0,0 +1 @@ +../../../../ios/firebase_storage/Sources/firebase_storage/FLTFirebaseStoragePlugin.swift \ No newline at end of file diff --git a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FLTTaskStateChannelStreamHandler.m b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FLTTaskStateChannelStreamHandler.m deleted file mode 120000 index fdc4ba297cbf..000000000000 --- a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FLTTaskStateChannelStreamHandler.m +++ /dev/null @@ -1 +0,0 @@ -../../../../ios/firebase_storage/Sources/firebase_storage/FLTTaskStateChannelStreamHandler.m \ No newline at end of file diff --git a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FirebaseStorageMessages.g.swift b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FirebaseStorageMessages.g.swift new file mode 120000 index 000000000000..2c852fb2483b --- /dev/null +++ b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/FirebaseStorageMessages.g.swift @@ -0,0 +1 @@ +../../../../ios/firebase_storage/Sources/firebase_storage/FirebaseStorageMessages.g.swift \ No newline at end of file diff --git a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/TaskStateChannelStreamHandler.swift b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/TaskStateChannelStreamHandler.swift new file mode 120000 index 000000000000..1f9775ba395f --- /dev/null +++ b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/TaskStateChannelStreamHandler.swift @@ -0,0 +1 @@ +../../../../ios/firebase_storage/Sources/firebase_storage/TaskStateChannelStreamHandler.swift \ No newline at end of file diff --git a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/firebase_storage_messages.g.m b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/firebase_storage_messages.g.m deleted file mode 120000 index 7db69a629c20..000000000000 --- a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/firebase_storage_messages.g.m +++ /dev/null @@ -1 +0,0 @@ -../../../../ios/firebase_storage/Sources/firebase_storage/firebase_storage_messages.g.m \ No newline at end of file diff --git a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/include/FLTFirebaseStoragePlugin.h b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/include/FLTFirebaseStoragePlugin.h deleted file mode 120000 index fd17c9a3165c..000000000000 --- a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/include/FLTFirebaseStoragePlugin.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../ios/firebase_storage/Sources/firebase_storage/include/FLTFirebaseStoragePlugin.h \ No newline at end of file diff --git a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/include/FLTTaskStateChannelStreamHandler.h b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/include/FLTTaskStateChannelStreamHandler.h deleted file mode 120000 index 897446c7f13d..000000000000 --- a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/include/FLTTaskStateChannelStreamHandler.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../ios/firebase_storage/Sources/firebase_storage/include/FLTTaskStateChannelStreamHandler.h \ No newline at end of file diff --git a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/include/firebase_storage_messages.g.h b/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/include/firebase_storage_messages.g.h deleted file mode 120000 index 7d19b22c7a47..000000000000 --- a/packages/firebase_storage/firebase_storage/macos/firebase_storage/Sources/firebase_storage/include/firebase_storage_messages.g.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../ios/firebase_storage/Sources/firebase_storage/include/firebase_storage_messages.g.h \ No newline at end of file diff --git a/packages/firebase_storage/firebase_storage/windows/messages.g.cpp b/packages/firebase_storage/firebase_storage/windows/messages.g.cpp index a77d577dc345..c4f093b94f48 100644 --- a/packages/firebase_storage/firebase_storage/windows/messages.g.cpp +++ b/packages/firebase_storage/firebase_storage/windows/messages.g.cpp @@ -1550,4 +1550,4 @@ EncodableValue FirebaseStorageHostApi::WrapError(const FlutterError& error) { error.details()}); } -} // namespace firebase_storage_windows +} // namespace firebase_storage_windows \ No newline at end of file diff --git a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart index 441ad5f1b400..cb10a718cc6b 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/lib/src/method_channel/method_channel_task.dart @@ -38,7 +38,13 @@ abstract class MethodChannelTask extends TaskPlatform { if (taskState == TaskState.error) { _didComplete = true; final errorMap = Map.from(events['error']); - final code = errorMap['code']; + String code = errorMap['code']; + + // If native surfaced an unknown error but we already transitioned the + // task snapshot to canceled (due to a local cancel), surface as canceled. + if (code != 'canceled' && snapshot.state == TaskState.canceled) { + code = 'canceled'; + } final exception = FirebaseException( plugin: 'firebase_storage', diff --git a/packages/firebase_storage/firebase_storage_platform_interface/pigeons/messages.dart b/packages/firebase_storage/firebase_storage_platform_interface/pigeons/messages.dart index a46b624dc4a6..bd36f3a6b57d 100644 --- a/packages/firebase_storage/firebase_storage_platform_interface/pigeons/messages.dart +++ b/packages/firebase_storage/firebase_storage_platform_interface/pigeons/messages.dart @@ -11,16 +11,13 @@ import 'package:pigeon/pigeon.dart'; dartOut: 'lib/src/pigeon/messages.pigeon.dart', // We export in the lib folder to expose the class to other packages. dartTestOut: 'test/pigeon/test_api.dart', - javaOut: - '../firebase_storage/android/src/main/java/io/flutter/plugins/firebase/storage/GeneratedAndroidFirebaseStorage.java', - javaOptions: JavaOptions( + kotlinOut: + '../firebase_storage/android/src/main/kotlin/io/flutter/plugins/firebase/storage/GeneratedAndroidFirebaseStorage.g.kt', + kotlinOptions: KotlinOptions( package: 'io.flutter.plugins.firebase.storage', - className: 'GeneratedAndroidFirebaseStorage', ), - objcHeaderOut: - '../firebase_storage/ios/firebase_storage/Sources/firebase_storage/include/firebase_storage_messages.g.h', - objcSourceOut: - '../firebase_storage/ios/firebase_storage/Sources/firebase_storage/firebase_storage_messages.g.m', + swiftOut: + '../firebase_storage/ios/firebase_storage/Sources/firebase_storage/FirebaseStorageMessages.g.swift', cppHeaderOut: '../firebase_storage/windows/messages.g.h', cppSourceOut: '../firebase_storage/windows/messages.g.cpp', cppOptions: CppOptions(namespace: 'firebase_storage_windows'), diff --git a/tests/android/app/build.gradle b/tests/android/app/build.gradle index 454ebf1be987..b26d90633bf5 100644 --- a/tests/android/app/build.gradle +++ b/tests/android/app/build.gradle @@ -25,7 +25,7 @@ if (flutterVersionName == null) { android { namespace = "io.flutter.plugins.firebase.tests" - compileSdk = 35 + compileSdk = 36 ndkVersion = flutter.ndkVersion compileOptions { @@ -41,7 +41,7 @@ android { defaultConfig { applicationId = "io.flutter.plugins.firebase.tests" // auth requires minSdk 23 - minSdk = 23 + minSdkVersion flutter.minSdkVersion targetSdk = 35 versionCode = flutterVersionCode.toInteger() versionName = flutterVersionName diff --git a/tests/ios/Flutter/AppFrameworkInfo.plist b/tests/ios/Flutter/AppFrameworkInfo.plist index 7c5696400627..1dc6cf7652ba 100644 --- a/tests/ios/Flutter/AppFrameworkInfo.plist +++ b/tests/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 12.0 + 13.0