Skip to content

Commit

Permalink
Support Android 15 (#127)
Browse files Browse the repository at this point in the history
* Bump compile sdk version to 35 and add replace jcenter with mavenCentral().

* Remove LeakCanary and upgrade Android Gradle Plugin.

* Update AGP version to fix compilation errors.

* Use updated maven plugin for deployment.

* Use updated maven publish plugin and support edge-to-edge.

* Update Sample project dependencies.

* Add CHANGELOG entry.

* Update unit test dependencies and fix unit tests.

* Update github workflow.

* Make target java version explicit.

* Update CHANGELOG with target Java SDK version.

* Revert target Java version to 8.

* Update CHANGELOG.md

Co-authored-by: Sarah Koop <skoop@paypal.com>

---------

Co-authored-by: Sarah Koop <skoop@paypal.com>
  • Loading branch information
sshropshire and sarahkoop authored Oct 3, 2024
1 parent f9145f6 commit 3228e03
Show file tree
Hide file tree
Showing 20 changed files with 244 additions and 159 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ jobs:
steps:
- name: Checkout Repository
uses: actions/checkout@v2
- name: Set up Java 8
- name: Set up Java 17
uses: actions/setup-java@v2
with:
java-version: '8'
java-version: '17'
distribution: 'zulu'
- name: Unit Tests
run: ./gradlew --stacktrace testRelease
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Android Card Form Release Notes

## unreleased
* Bump `compileSdkVersion` and `targetSdkVersion` to API level 35

## 5.4.0
* Update Visa card icon

Expand Down
91 changes: 23 additions & 68 deletions CardForm/build.gradle
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
plugins {
id 'com.android.library'
id 'de.marcphilipp.nexus-publish'
id 'signing'
}

android {
compileSdkVersion rootProject.compileSdkVersion
buildToolsVersion '30.0.2'
compileSdk rootProject.compileSdkVersion
namespace "com.braintreepayments.cardform"

defaultConfig {
minSdkVersion rootProject.minSdkVersion
targetSdkVersion rootProject.targetSdkVersion
versionCode rootProject.versionCode
versionName rootProject.versionName
}

testOptions {
unitTests {
includeAndroidResources true
includeAndroidResources = true
all {
jvmArgs '-noverify'
}
}
}

Expand All @@ -26,18 +25,23 @@ android {
textOutput 'stdout'
}

compileOptions {
sourceCompatibility versions.javaSourceCompatibility
targetCompatibility versions.javaTargetCompatibility
}

resourcePrefix 'bt_'
}

dependencies {
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'com.google.android.flexbox:flexbox:3.0.0'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'androidx.recyclerview:recyclerview:1.3.2'

testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.8.9'
testImplementation 'org.robolectric:robolectric:4.3'
testImplementation 'androidx.test:core:1.4.0'
testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:5.7.0'
testImplementation 'org.robolectric:robolectric:4.13'
testImplementation 'androidx.test:core:1.6.1'
}

// region signing and publishing
Expand All @@ -63,61 +67,12 @@ artifacts {
archives sourcesJar
}

signing {
required {
!version.endsWith("SNAPSHOT") && !version.endsWith("DEVELOPMENT")
}
sign publishing.publications
}

nexusPublishing {
// give nexus sonatype more time to initialize the staging repository
clientTimeout = Duration.ofMinutes(3)
repositories {
sonatype()
}
}
project.ext.name = "card-form"
project.ext.pom_name = "card-form"
project.ext.group_id = "com.braintreepayments"
project.ext.version = rootProject.version
project.ext.pom_desc = "A ready-made card form layout that can be included in your Android app, making it easy to accept credit and debit cards."

afterEvaluate {
publishing {
publications {
release(MavenPublication) {
from components.release

groupId = 'com.braintreepayments'
artifactId = 'card-form'
version = rootProject.versionName

pom {
name = 'card-form'
packaging = 'aar'
description = 'A ready-made card form layout that can be included in your Android app, making it easy to accept credit and debit cards.'
url = 'https://github.com/braintree/android-card-form'

scm {
url = 'scm:git@github.com:braintree/android-card-form.git'
connection = 'scm:git@github.com:braintree/android-card-form.git'
developerConnection = 'scm:git@github.com:braintree/android-card-form.git'
}

developers {
developer {
id = 'devs'
name = 'Braintree Payments'
}
}

licenses {
license {
name = 'MIT'
url = 'http://opensource.org/licenses/MIT'
distribution = 'repo'
}
}
}
}
}
}
}
apply from: rootProject.file("gradle/gradle-publish.gradle")

// endregion
3 changes: 1 addition & 2 deletions CardForm/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="com.braintreepayments.cardform">
</manifest>
<manifest />
9 changes: 9 additions & 0 deletions CardForm/src/test/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application>
<activity
android:name=".test.TestActivity"
android:theme="@style/Theme.AppCompat" />
</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,8 @@ public class TestActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setTheme(androidx.appcompat.R.style.Theme_AppCompat);
super.onCreate(savedInstanceState);

CardForm cardForm = new CardForm(this);
cardForm.setId(android.R.id.custom);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@

import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.verifyNoInteractions;
import static org.mockito.Mockito.when;

@RunWith(RobolectricTestRunner.class)
Expand Down Expand Up @@ -49,7 +49,7 @@ public void vibrate_doesNotCallVibrateIfHasVibratePermissionIsFalse() {

VibrationHelper.vibrate(context, 1000);

verifyZeroInteractions(vibrator);
verifyNoInteractions(vibrator);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@
@RunWith(RobolectricTestRunner.class)
public class ErrorEditTextTest {

private TestActivity mActivity;
private ErrorEditText mView;

@Before
public void setup() {
mView = new ErrorEditText(RuntimeEnvironment.application);
mActivity = Robolectric.setupActivity(TestActivity.class);
mView = new ErrorEditText(mActivity);
}

@Test
public void setFieldHint_setsHintWhenParentViewIsATextInputLayout() {
mView = (CardEditText) Robolectric.setupActivity(TestActivity.class)
.findViewById(R.id.bt_card_form_card_number);

mView = mActivity.findViewById(R.id.bt_card_form_card_number);
mView.setFieldHint(R.string.bt_form_hint_cvv);

assertEquals("CVV", ((TextInputLayout) mView.getParent().getParent()).getHint());
Expand All @@ -41,9 +41,7 @@ public void setFieldHint_setsHintWhenParentViewIsATextInputLayout() {

@Test
public void setFieldHint_setsHintStringWhenParentViewIsATextInputLayout() {
mView = (CardEditText) Robolectric.setupActivity(TestActivity.class)
.findViewById(R.id.bt_card_form_card_number);

mView = mActivity.findViewById(R.id.bt_card_form_card_number);
mView.setFieldHint("CVV");

assertEquals("CVV", ((TextInputLayout) mView.getParent().getParent()).getHint());
Expand Down Expand Up @@ -99,9 +97,7 @@ public void getErrorMessage_returnsNull() {

@Test
public void setError_setsErrorWhenParentViewIsATextInputLayout() {
mView = (CardEditText) Robolectric.setupActivity(TestActivity.class)
.findViewById(R.id.bt_card_form_card_number);

mView = mActivity.findViewById(R.id.bt_card_form_card_number);
mView.setError("Error");

assertEquals("Error", ((TextInputLayout) mView.getParent().getParent()).getError());
Expand All @@ -126,7 +122,7 @@ public void setError_clearsErrorWhenMessageNullOrEmpty() {

@Test
public void validate_showsErrorMessage() {
mView = new ErrorEditText(RuntimeEnvironment.application) {
mView = new ErrorEditText(mActivity) {
@Override
public boolean isValid() {
return false;
Expand All @@ -145,7 +141,7 @@ public String getErrorMessage() {

@Test
public void validate_doesNotShowErrorMessageIfOptional() {
mView = new ErrorEditText(RuntimeEnvironment.application) {
mView = new ErrorEditText(mActivity) {
@Override
public boolean isValid() {
return false;
Expand All @@ -165,8 +161,7 @@ public String getErrorMessage() {

@Test
public void getTextInputLayoutParent_returnsTextInputLayout() {
mView = (CardEditText) Robolectric.setupActivity(TestActivity.class)
.findViewById(R.id.bt_card_form_card_number);
mView = mActivity.findViewById(R.id.bt_card_form_card_number);

assertNotNull(mView.getTextInputLayoutParent());
}
Expand Down
15 changes: 7 additions & 8 deletions Sample/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ plugins {
}

android {
compileSdkVersion rootProject.compileSdkVersion
buildToolsVersion '30.0.2'
compileSdk rootProject.compileSdkVersion
namespace "com.braintreepayments.sample"

defaultConfig {
applicationId 'com.braintreepayments.sample'
Expand All @@ -26,13 +26,12 @@ android {
dependencies {
implementation project(':CardForm')

implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'com.facebook.stetho:stetho:1.5.0'
implementation 'com.google.android.material:material:1.0.0'
implementation 'com.squareup.leakcanary:leakcanary-android:1.4'
implementation 'com.google.android.material:material:1.12.0'

androidTestImplementation 'androidx.test:core:1.0.0'
androidTestImplementation 'androidx.test:rules:1.1.0'
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test:core:1.6.1'
androidTestImplementation 'androidx.test:rules:1.6.1'
androidTestImplementation 'androidx.test:runner:1.6.2'
androidTestImplementation 'com.braintreepayments:device-automator:1.0.0'
}
24 changes: 13 additions & 11 deletions Sample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.braintreepayments.sample">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<uses-permission android:name="android.permission.VIBRATE" />

<application
android:allowBackup="true"
android:supportsRtl="true"
android:name=".SampleApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.Holo.Light"
android:icon="@mipmap/ic_launcher">
android:supportsRtl="true"
android:theme="@style/Theme.AppCompat.NoActionBar">

<activity android:name=".SampleActivity"
android:theme="@style/Theme.AppCompat"
android:label="@string/app_name">
<activity
android:name=".SampleActivity"
android:exported="true"
android:theme="@style/Theme.AppCompat.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<activity android:name=".LightThemeActivity"
<activity
android:name=".LightThemeActivity"
android:theme="@style/LightTheme" />

<activity android:name=".DarkThemeActivity"
<activity
android:name=".DarkThemeActivity"
android:theme="@style/DarkTheme" />
</application>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package com.braintreepayments.sample;

import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.braintreepayments.cardform.OnCardFormSubmitListener;
import com.braintreepayments.cardform.utils.CardType;
Expand Down Expand Up @@ -51,6 +55,17 @@ protected void onCreate(Bundle savedInstanceState) {
// Warning: this is for development purposes only and should never be done outside of this example app.
// Failure to set FLAG_SECURE exposes your app to screenshots allowing other apps to steal card information.
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE);

// Support Edge-to-Edge layout in Android 15
// Ref: https://developer.android.com/develop/ui/views/layout/edge-to-edge#cutout-insets
View navHostView = findViewById(R.id.content);
ViewCompat.setOnApplyWindowInsetsListener(navHostView, (v, insets) -> {
@WindowInsetsCompat.Type.InsetsType int insetTypeMask =
WindowInsetsCompat.Type.systemBars() | WindowInsetsCompat.Type.displayCutout();
Insets bars = insets.getInsets(insetTypeMask);
v.setPadding(bars.left, bars.top, bars.right, bars.bottom);
return WindowInsetsCompat.CONSUMED;
});
}

@Override
Expand Down
Loading

0 comments on commit 3228e03

Please sign in to comment.