diff --git a/authentication/build.gradle.kts b/authentication/build.gradle.kts
index 7a701b0e..3e912701 100644
--- a/authentication/build.gradle.kts
+++ b/authentication/build.gradle.kts
@@ -47,9 +47,17 @@ android {
}
buildTypes { release { isMinifyEnabled = false } }
+
+ buildFeatures { compose = true }
+ composeOptions { kotlinCompilerExtensionVersion = "1.5.11" }
}
dependencies {
+ implementation(libs.androidx.ui.tooling.preview.android)
+ val composeBom = platform(libs.compose.bom)
+ implementation(composeBom)
+ implementation(libs.androidx.compose.foundation)
+ implementation(libs.material3)
implementation(libs.appCompat)
implementation(libs.chrometabs)
implementation(libs.material)
diff --git a/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/LoginButton.kt b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/LoginButton.kt
new file mode 100644
index 00000000..c33d167f
--- /dev/null
+++ b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/LoginButton.kt
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2016. Uber Technologies
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.uber.sdk2.auth.ui
+
+import android.content.Context
+import android.util.AttributeSet
+import androidx.annotation.StringRes
+import androidx.annotation.StyleRes
+import androidx.annotation.VisibleForTesting
+import com.uber.sdk2.auth.R
+import com.uber.sdk2.auth.UberAuthClientImpl
+import com.uber.sdk2.auth.request.AuthContext
+import com.uber.sdk2.core.ui.UberStyle
+import com.uber.sdk2.core.ui.legacy.UberButton
+
+/** The [LoginButton] is used to initiate the Uber SDK Login flow. */
+class LoginButton : UberButton {
+ private var authContext: AuthContext? = null
+
+ constructor(context: Context) : super(context)
+
+ constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
+
+ constructor(
+ context: Context,
+ attrs: AttributeSet?,
+ defStyleAttr: Int,
+ ) : super(context, attrs, defStyleAttr)
+
+ constructor(
+ context: Context,
+ attrs: AttributeSet?,
+ defStyleAttr: Int,
+ defStyleRes: Int,
+ ) : super(context, attrs, defStyleAttr, defStyleRes)
+
+ override fun init(
+ context: Context,
+ @StringRes defaultText: Int,
+ attrs: AttributeSet?,
+ defStyleAttr: Int,
+ uberStyle: UberStyle,
+ ) {
+ isAllCaps = true
+
+ val defStyleRes = STYLES[uberStyle.value]
+
+ applyStyle(context, R.string.ub__sign_in, attrs, defStyleAttr, defStyleRes)
+
+ setOnClickListener { login() }
+ }
+
+ @VisibleForTesting
+ fun login() {
+ val activity = activity
+ UberAuthClientImpl().authenticate(activity, authContext!!)
+ }
+
+ /**
+ * A [AuthContext] is required to identify the app being authenticated.
+ *
+ * @param authContext to be identified.
+ * @return this instance of [LoginButton]
+ */
+ fun authContext(authContext: AuthContext): LoginButton {
+ this.authContext = authContext
+ return this
+ }
+
+ companion object {
+ @StyleRes
+ private val STYLES = intArrayOf(R.style.UberButton_Login, R.style.UberButton_Login_White)
+ }
+}
diff --git a/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/UberAuthButton.kt b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/UberAuthButton.kt
new file mode 100644
index 00000000..072281ce
--- /dev/null
+++ b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/UberAuthButton.kt
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2024. Uber Technologies
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.uber.sdk2.auth.ui
+
+import androidx.compose.foundation.interaction.MutableInteractionSource
+import androidx.compose.foundation.interaction.collectIsPressedAsState
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.wrapContentSize
+import androidx.compose.foundation.layout.wrapContentWidth
+import androidx.compose.material3.Button
+import androidx.compose.material3.ButtonDefaults
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import com.uber.sdk2.auth.ui.theme.UberDimens
+import com.uber.sdk2.auth.ui.theme.UberTypography
+import com.uber.sdk2.core.R
+
+@Composable
+fun UberAuthButton(
+ isWhite: Boolean = false,
+ shape: Shape = MaterialTheme.shapes.large,
+ onClick: () -> Unit,
+) {
+ val text = stringResource(id = com.uber.sdk2.auth.R.string.ub__sign_in)
+ val interactionSource = remember { MutableInteractionSource() }
+ val isPressed = interactionSource.collectIsPressedAsState().value
+ val backgroundColor =
+ if (isPressed) {
+ MaterialTheme.colorScheme.onSecondary
+ } else {
+ MaterialTheme.colorScheme.onPrimary
+ }
+
+ val textColor = MaterialTheme.colorScheme.primary
+
+ val iconResId = if (isWhite) R.drawable.uber_logotype_black else R.drawable.uber_logotype_white
+
+ Button(
+ onClick = onClick,
+ modifier = Modifier.wrapContentSize(),
+ colors =
+ ButtonDefaults.buttonColors(containerColor = backgroundColor, contentColor = textColor),
+ shape = shape,
+ interactionSource = interactionSource,
+ ) {
+ Icon(
+ painter = painterResource(id = iconResId),
+ contentDescription = null,
+ modifier = Modifier.padding(end = UberDimens.signInMargin),
+ )
+ Text(
+ text = text.uppercase(),
+ color = textColor,
+ style = UberTypography.bodyMedium,
+ modifier = Modifier.padding(UberDimens.standardPadding).wrapContentWidth(),
+ )
+ }
+}
diff --git a/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberButtonAttributes.kt b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberButtonAttributes.kt
new file mode 100644
index 00000000..2413aae7
--- /dev/null
+++ b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberButtonAttributes.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024. Uber Technologies
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.uber.sdk2.auth.ui.theme
+
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.Shapes
+import androidx.compose.ui.unit.dp
+
+val UberButtonShapes =
+ Shapes(
+ small = RoundedCornerShape(4.dp),
+ medium = RoundedCornerShape(8.dp),
+ large = RoundedCornerShape(16.dp),
+ )
+
+object UberDimens {
+ val smallPadding = 8.dp
+ val standardPadding = 16.dp
+ val signInMargin = 48.dp
+}
diff --git a/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberColorPalette.kt b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberColorPalette.kt
new file mode 100644
index 00000000..c8789a40
--- /dev/null
+++ b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberColorPalette.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024. Uber Technologies
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.uber.sdk2.auth.ui.theme
+
+import androidx.compose.ui.graphics.Color
+
+val UberBlack = Color(0xFF000000)
+val UberBlack90 = Color(0xFF282727)
+val UberWhite = Color(0xFFFFFFFF)
+val UberWhite40 = Color(0xFFE5E5E4)
diff --git a/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberTheme.kt b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberTheme.kt
new file mode 100644
index 00000000..a269d8f4
--- /dev/null
+++ b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberTheme.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2024. Uber Technologies
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.uber.sdk2.auth.ui.theme
+
+import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.darkColorScheme
+import androidx.compose.material3.lightColorScheme
+import androidx.compose.runtime.Composable
+
+@Composable
+fun UberTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) {
+ val colors =
+ if (darkTheme) {
+ darkColorScheme(primary = UberBlack, onPrimary = UberWhite, onSecondary = UberWhite40)
+ } else {
+ lightColorScheme(primary = UberWhite, onPrimary = UberBlack, onSecondary = UberBlack90)
+ }
+
+ MaterialTheme(
+ colorScheme = colors,
+ typography = UberTypography,
+ shapes = UberButtonShapes,
+ content = content,
+ )
+}
diff --git a/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberTypography.kt b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberTypography.kt
new file mode 100644
index 00000000..94ae9caa
--- /dev/null
+++ b/authentication/src/main/kotlin/com/uber/sdk2/auth/ui/theme/UberTypography.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024. Uber Technologies
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.uber.sdk2.auth.ui.theme
+
+import androidx.compose.material3.Typography
+import androidx.compose.ui.text.TextStyle
+import androidx.compose.ui.unit.sp
+
+val UberTypography =
+ Typography(
+ bodySmall = TextStyle(fontSize = 12.sp),
+ bodyMedium = TextStyle(fontSize = 14.sp),
+ bodyLarge = TextStyle(fontSize = 20.sp),
+ )
diff --git a/authentication/src/main/res/values-hi-rIN/strings_localized.xml b/authentication/src/main/res/values-hi-rIN/strings_localized.xml
new file mode 100644
index 00000000..886d2422
--- /dev/null
+++ b/authentication/src/main/res/values-hi-rIN/strings_localized.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ साइन इन करें
+
diff --git a/authentication/src/main/res/values-zh-rCN/strings_localized.xml b/authentication/src/main/res/values-zh-rCN/strings_localized.xml
new file mode 100644
index 00000000..26a8d8d5
--- /dev/null
+++ b/authentication/src/main/res/values-zh-rCN/strings_localized.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ 登录
+
diff --git a/authentication/src/main/res/values-zh-rHK/strings_localized.xml b/authentication/src/main/res/values-zh-rHK/strings_localized.xml
new file mode 100644
index 00000000..55912c52
--- /dev/null
+++ b/authentication/src/main/res/values-zh-rHK/strings_localized.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ Sign in
+
diff --git a/authentication/src/main/res/values-zh-rTW/strings_localized.xml b/authentication/src/main/res/values-zh-rTW/strings_localized.xml
new file mode 100644
index 00000000..cd8bc4a7
--- /dev/null
+++ b/authentication/src/main/res/values-zh-rTW/strings_localized.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ 登入
+
diff --git a/authentication/src/main/res/values/strings_localized.xml b/authentication/src/main/res/values/strings_localized.xml
new file mode 100644
index 00000000..55912c52
--- /dev/null
+++ b/authentication/src/main/res/values/strings_localized.xml
@@ -0,0 +1,20 @@
+
+
+
+
+ Sign in
+
diff --git a/authentication/src/main/res/values/styles.xml b/authentication/src/main/res/values/styles.xml
new file mode 100644
index 00000000..93fcffe9
--- /dev/null
+++ b/authentication/src/main/res/values/styles.xml
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/core/src/main/kotlin/com/uber/sdk2/core/utils/CustomTabsHelper.kt b/core/src/main/kotlin/com/uber/sdk2/core/utils/CustomTabsHelper.kt
index cbe5fe28..57c2fccf 100644
--- a/core/src/main/kotlin/com/uber/sdk2/core/utils/CustomTabsHelper.kt
+++ b/core/src/main/kotlin/com/uber/sdk2/core/utils/CustomTabsHelper.kt
@@ -48,10 +48,10 @@ object CustomTabsHelper {
) {
val packageName = getPackageNameToUse(context)
if (packageName != null) {
- connection =
+ val connection =
object : CustomTabsServiceConnection() {
override fun onCustomTabsServiceConnected(
- componentName: ComponentName?,
+ componentName: ComponentName,
client: CustomTabsClient,
) {
client.warmup(0L) // This prevents backgrounding after redirection
@@ -63,6 +63,7 @@ object CustomTabsHelper {
override fun onServiceDisconnected(name: ComponentName?) {}
}
CustomTabsClient.bindCustomTabsService(context, packageName, connection)
+ this.connection = connection
} else
fallback?.openUri(context, uri)
?: Log.e(
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index e234dfa8..1c9000fc 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -2,7 +2,7 @@
[versions]
agp = "8.2.2"
-androidxVersion = "1.0.0"
+androidxVersion = "1.7.0"
uberJava = "0.8.5"
mavenPublish = "0.27.0"
kotlin = "1.9.23"
diff --git a/samples/login-sample/src/main/java/com/uber/sdk/android/samples/LoginSampleActivity.java b/samples/login-sample/src/main/java/com/uber/sdk/android/samples/LoginSampleActivity.java
index ac28664a..5ab10550 100644
--- a/samples/login-sample/src/main/java/com/uber/sdk/android/samples/LoginSampleActivity.java
+++ b/samples/login-sample/src/main/java/com/uber/sdk/android/samples/LoginSampleActivity.java
@@ -147,6 +147,7 @@ protected void onResume() {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
Log.i(LOG_TAG, String.format("onActivityResult requestCode:[%s] resultCode [%s]",
requestCode, resultCode));
diff --git a/samples/login-with-auth-code-demo/src/main/java/com/uber/sdk/android/samples/DemoActivity.java b/samples/login-with-auth-code-demo/src/main/java/com/uber/sdk/android/samples/DemoActivity.java
index b9b2c2bd..d8d53d57 100644
--- a/samples/login-with-auth-code-demo/src/main/java/com/uber/sdk/android/samples/DemoActivity.java
+++ b/samples/login-with-auth-code-demo/src/main/java/com/uber/sdk/android/samples/DemoActivity.java
@@ -92,6 +92,7 @@ protected void onCreate(Bundle savedInstanceState) {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
Log.i(LOG_TAG, String.format("onActivityResult requestCode:[%s] resultCode [%s]",
requestCode, resultCode));
if (data != null) {