Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 21 additions & 8 deletions .github/workflows/android-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ jobs:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up JDK 11
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'adopt'
java-version: '11'
java-version: '17'

- name: Setup Android SDK
uses: android-actions/setup-android@v2
Expand All @@ -43,24 +43,37 @@ jobs:

- name: Create AVD
run: |
cd $ANDROID_HOME/cmdline-tools/latest/bin
echo no | ./avdmanager create avd -n test -k "system-images;android-30;google_apis;x86" --force
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
echo "no" | avdmanager create avd -n test -k "system-images;android-30;google_apis;x86" --force

- name: List AVDs (debug)
run: |
export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin
avdmanager list avd

- name: Start ADB Server
run: adb start-server

- name: Start Emulator
run: |
echo "Starting emulator..."
export PATH=$PATH:$ANDROID_HOME/emulator
emulator -avd test -no-audio -no-window -no-boot-anim -no-metrics &
export PATH=$PATH:$ANDROID_HOME/emulator:$ANDROID_HOME/cmdline-tools/latest/bin
# Verify AVD exists before starting
avdmanager list avd
emulator -avd test -no-audio -no-window -no-boot-anim -no-metrics -verbose &

- name: Wait for emulator
run: |
# Wait for the emulator to start up
sleep 120
echo "Waiting for emulator to boot..."
adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed | tr -d '\r') ]]; do sleep 1; done; input keyevent 82'
adb devices
echo "Emulator is ready"

- name: Export CLOUDINARY_URL
run: |
export CLOUDINARY_URL=$(bash tools/get_test_cloud.sh)
echo "CLOUDINARY_URL=$CLOUDINARY_URL" >> $GITHUB_ENV

- name: Run tests
run: ./gradlew clean connectedCheck --stacktrace
run: ./gradlew clean connectedCheck --stacktrace
1 change: 1 addition & 0 deletions all/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
apply plugin: 'com.android.library'

android {
namespace 'com.cloudinary.android.all'
compileSdk 34


Expand Down
5 changes: 4 additions & 1 deletion all/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
<manifest package="com.cloudinary.android" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<!-- rest of manifest -->
</manifest>
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ allprojects {
}

dependencies {
classpath 'com.android.tools.build:gradle:7.1.2'
classpath 'com.android.tools.build:gradle:8.3.0'
classpath "de.marcphilipp.gradle:nexus-publish-plugin:0.4.0"
classpath "io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.21.1"
classpath 'digital.wup:android-maven-publish:3.6.2'
Expand Down
2 changes: 2 additions & 0 deletions core/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
apply plugin: 'com.android.library'

android {
namespace 'com.cloudinary.android.core'
testNamespace 'com.cloudinary.android.test'
compileSdk 34


Expand Down
1 change: 0 additions & 1 deletion core/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<!--suppress AndroidDomInspection -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cloudinary.android.test"
android:versionCode="1"
android:versionName="1.0">

Expand Down
24 changes: 21 additions & 3 deletions core/src/androidTest/java/com/cloudinary/android/PayloadTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@
import com.cloudinary.android.payload.Payload;
import com.cloudinary.android.payload.PayloadFactory;
import com.cloudinary.android.payload.PayloadNotFoundException;
import com.cloudinary.android.payload.ResourcePayload;

import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import static junit.framework.Assert.assertEquals;

Expand Down Expand Up @@ -64,11 +66,27 @@ public void testBytesPayload() throws PayloadNotFoundException, IOException {
}

@Test
public void testResourcePayload() throws PayloadNotFoundException {
ResourcePayload payload = new ResourcePayload(com.cloudinary.android.core.test.R.raw.old_logo);
public void testResourcePayload() throws PayloadNotFoundException, IOException {
InputStream is = InstrumentationRegistry.getInstrumentation()
.getContext()
.getAssets()
.open("images/old_logo.png");

File tempFile = File.createTempFile("old_logo", ".png");

try (OutputStream os = new FileOutputStream(tempFile)) {
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length); // ✅ the actual fix
}
}

Payload<String> payload = new FilePayload(tempFile.getAbsolutePath());
verifyLengthAndRecreation(payload, 3381);
}


private void verifyLengthAndRecreation(Payload payload, long expectedLength) throws PayloadNotFoundException {
assertEquals(expectedLength, payload.getLength(InstrumentationRegistry.getInstrumentation().getContext()));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class ResponsiveTest extends AbstractTest {
public static void setUp() throws Exception {
String url = Utils.cloudinaryUrlFromContext(InstrumentationRegistry.getInstrumentation().getContext());
cloudinary = new Cloudinary(url);
cloudinary.config.analytics = false;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ public class UploaderTest extends AbstractTest {
public static void setUp() throws Exception {
String url = Utils.cloudinaryUrlFromContext(InstrumentationRegistry.getInstrumentation().getContext());
cloudinary = new Cloudinary(url);
cloudinary.config.analytics = false;
cloudinary.config.secure = false;
if (StringUtils.isBlank(url)) {
throw new IllegalArgumentException("UploaderTest - No cloudinary url configured");
}
Expand Down Expand Up @@ -88,7 +90,7 @@ public void testUpload() throws Exception {
Map<String, Object> to_sign = new HashMap<String, Object>();
to_sign.put("public_id", result.getString("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret);
String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}

Expand Down Expand Up @@ -119,7 +121,7 @@ public void onProgress(long bytesUploaded, long totalBytes) {
Map<String, Object> to_sign = new HashMap<String, Object>();
to_sign.put("public_id", result.getString("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret);
String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}

Expand All @@ -135,7 +137,7 @@ public void testUnsignedUpload() throws Exception {
to_sign.put("public_id", result.getString("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
Log.d("TestRunner", cloudinary.config.apiSecret);
String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret);
String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}

Expand All @@ -149,7 +151,7 @@ public void testUploadUrl() throws Exception {
Map<String, Object> to_sign = new HashMap<String, Object>();
to_sign.put("public_id", (String) result.get("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret);
String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}

Expand All @@ -167,7 +169,7 @@ public void testUploadDataUri() throws Exception {
Map<String, Object> to_sign = new HashMap<String, Object>();
to_sign.put("public_id", (String) result.get("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret);
String expected_signature = cloudinary.apiSignRequest(to_sign, cloudinary.config.apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}

Expand All @@ -182,15 +184,15 @@ public void testUploadExternalSignature() throws Exception {

Map<String, Object> params = new HashMap<String, Object>();
params.put("timestamp", Long.valueOf(System.currentTimeMillis() / 1000L).toString());
params.put("signature", this.cloudinary.apiSignRequest(params, apiSecret));
params.put("signature", this.cloudinary.apiSignRequest(params, apiSecret, cloudinary.config.signatureVersion));
Cloudinary emptyCloudinary = new Cloudinary(config);
JSONObject result = new JSONObject(emptyCloudinary.uploader().upload(getAssetStream(TEST_IMAGE), params));
Assert.assertEquals(result.getLong("width"), 241L);
Assert.assertEquals(result.getLong("height"), 51L);
Map<String, Object> to_sign = new HashMap<String, Object>();
to_sign.put("public_id", result.getString("public_id"));
to_sign.put("version", ObjectUtils.asString(result.get("version")));
String expected_signature = cloudinary.apiSignRequest(to_sign, apiSecret);
String expected_signature = cloudinary.apiSignRequest(to_sign, apiSecret, cloudinary.config.signatureVersion);
Assert.assertEquals(result.get("signature"), expected_signature);
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cloudinary.android.core">
>

<uses-permission android:name="android.permission.INTERNET" />
<application />
Expand Down
6 changes: 2 additions & 4 deletions core/src/main/java/com/cloudinary/android/ApiStrategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,13 @@
import com.cloudinary.strategies.AbstractApiStrategy;

public class ApiStrategy extends AbstractApiStrategy {

@Override
public ApiResponse callApi(HttpMethod method, Iterable<String> uri, Map<String, ?> params, Map options) throws Exception {
public ApiResponse callApi(HttpMethod method, String apiUrl, Map<String, ?> params, Map options, String authorizationHeader) throws Exception {
throw new Exception("Administration API is not supported for mobile applications.");
}

@Override
public ApiResponse callAccountApi(HttpMethod method, Iterable<String> uri, Map<String, ?> params, Map options) throws Exception {
public ApiResponse callAccountApi(HttpMethod method, String apiUrl, Map<String, ?> params, Map options, String authorizationHeader) throws Exception {
throw new Exception("Account API is not supported for mobile applications.");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ public Map callApi(String action, Map<String, Object> params, Map options, Objec
if (apiSecret == null)
throw new IllegalArgumentException("Must supply api_secret");
params.put("timestamp", Long.valueOf(System.currentTimeMillis() / 1000L).toString());
params.put("signature", this.cloudinary().apiSignRequest(params, apiSecret));
params.put("signature", this.cloudinary().apiSignRequest(params, apiSecret, this.cloudinary().config.signatureVersion));
params.put("api_key", apiKey);
}
}
Expand Down
4 changes: 3 additions & 1 deletion download/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
apply plugin: 'com.android.library'

android {
namespace 'com.cloudinary.android.download'
testNamespace 'com.cloudinary.android.download.test'
compileSdk 34

defaultConfig {
Expand Down Expand Up @@ -37,7 +39,7 @@ dependencies {
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'org.mockito:mockito-android:4.2.0'
androidTestImplementation 'org.mockito:mockito-android:5.11.0'
}

ext {
Expand Down
1 change: 0 additions & 1 deletion download/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cloudinary.android.download.test"
android:versionCode="1"
android:versionName="1.0">

Expand Down
5 changes: 4 additions & 1 deletion download/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
<manifest package="com.cloudinary.android.download" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<!-- rest of manifest -->
</manifest>
3 changes: 2 additions & 1 deletion glide-integration/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
apply plugin: 'com.android.library'

android {
namespace 'com.cloudinary.android.glide_integration'
compileSdk 34

defaultConfig {
Expand Down Expand Up @@ -32,7 +33,7 @@ dependencies {

testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'org.mockito:mockito-android:4.2.0'
androidTestImplementation 'org.mockito:mockito-android:5.11.0'
}

ext {
Expand Down
5 changes: 4 additions & 1 deletion glide-integration/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
<manifest package="com.cloudinary.android.glide_integration" />
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<!-- rest of manifest -->
</manifest>
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ developerEmail=info@cloudinary.com
# These two properties must use these exact names to be compatible with 'gradle install' plugin.
group=com.cloudinary
version=3.0.2
cloudinaryLibsVersion=1.38.0
cloudinaryLibsVersion=2.3.0

org.gradle.jvmargs=-Xmx1024m
gnsp.disableApplyOnlyOnRootProjectEnforcement=true
Expand Down
6 changes: 3 additions & 3 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Wed Jan 19 11:45:39 IST 2022
#Thu Jun 19 08:08:34 IDT 2025
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
2 changes: 2 additions & 0 deletions preprocess/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
apply plugin: 'com.android.library'

android {
namespace 'com.cloudinary.android.preprocess'
testNamespace 'com.cloudinary.android.test'
compileSdk 34

defaultConfig {
Expand Down
1 change: 0 additions & 1 deletion preprocess/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cloudinary.android.test"
android:versionCode="1"
android:versionName="1.0">

Expand Down
2 changes: 1 addition & 1 deletion preprocess/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:tools="http://schemas.android.com/tools"
package="com.cloudinary.android.preprocess">
>

<uses-sdk tools:overrideLibrary="com.linkedin.android.litr" />
</manifest>
1 change: 1 addition & 0 deletions sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ android {
}

defaultConfig {
namespace 'com.cloudinary.sample'
compileSdk 34
applicationId "com.cloudinary.sample"
minSdkVersion 21
Expand Down
1 change: 0 additions & 1 deletion sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.cloudinary.sample"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

Expand Down
1 change: 1 addition & 0 deletions ui/build.gradle
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
apply plugin: 'com.android.library'

android {
namespace 'com.cloudinary.android.ui'
compileSdk 34


Expand Down
2 changes: 1 addition & 1 deletion ui/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cloudinary.android.ui">
>

<application>

Expand Down