Skip to content

Commit

Permalink
Upgrade NativeAppLoginMethodHandler to launch intents with ActivityLa…
Browse files Browse the repository at this point in the history
…uncher

Summary:
When upgrading to AndroidX Activity/Fragment 1.5.1, if FB4A is not installed then the backup CCT flow will break.

The following video is HB4A using Android Acitivty/Fragment 1.5.1 and reproducing the CCT problem. Note that nothing can be clicked on after the login flow is complete. Then clicking the back button says no permissions were granted.
https://pxl.cl/2bHRd

The root cause of the issue is that there were internal changes for the 1.5.1 update and using startActivityForResult does not trigger onActivityResult correctly. This seems to only happen when you try to start an activity when it doesn't exist.

In NativeAppLoginMethodHandler, we can't tell if FB4A is installed so we just attempt to start the activity and catch the ActivityNotFoundException if it does not start. If the native flow cannot be attempted, then we fallback to CCT flow. For some reason, after failing to start the FB4A intent, the LoginFragment does not correctly trigger the onActivityResult function when the backup CCT flow completes. The error also seems to occur if you click cancel on the CCT flow.

This diff updates the LoginFragment to have a new ActivityLauncher member and updates NativeAppLoginMethodHandler to use the launcher to launch the FB4A intent. We also now query for the intent instead of try/catch the start attempt. It seems this is the primary issue.

In 1.4.0 and below, if an activity cannot be started, it will still trigger the on result flow.
In 1.5.0 and above, if an activity cannot be started, it will not trigger the on result flow.

Reviewed By: ct2mak

Differential Revision:
D38929817 (d7d4e0d)

------------------------------------------------------------------------
(from b985157050e1b9c68627c97055cd93d83f3c3752)

fbshipit-source-id: ba7f62fcff18b734a047c7e88c09268f25d9db4a
  • Loading branch information
Aaron Chau authored and facebook-github-bot committed Aug 29, 2022
1 parent b8c6dd7 commit 1ad14c9
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 11 deletions.
3 changes: 3 additions & 0 deletions facebook-common/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@

<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
package="com.facebook.common">
<queries>
<package android:name="com.facebook.katana" />
</queries>

<application>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.activity.result.ActivityResult
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.LayoutRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.facebook.common.R

/**
Expand All @@ -39,9 +43,11 @@ import com.facebook.common.R
*/
open class LoginFragment : Fragment() {
private var callingPackage: String? = null
private var request: LoginClient.Request? = null
lateinit var loginClient: LoginClient
private set
private var request: LoginClient.Request? = null
lateinit var launcher: ActivityResultLauncher<Intent>
private set

private lateinit var progressBar: View

Expand All @@ -66,8 +72,23 @@ open class LoginFragment : Fragment() {
request = bundle.getParcelable(EXTRA_REQUEST)
}
}

launcher =
registerForActivityResult(
ActivityResultContracts.StartActivityForResult(),
getLoginMethodHandlerCallback(activity))
}

private fun getLoginMethodHandlerCallback(activity: FragmentActivity): (ActivityResult) -> Unit =
{ result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
loginClient.onActivityResult(
LoginClient.getLoginRequestCode(), result.resultCode, result.data)
} else {
activity.finish()
}
}

protected open fun createLoginClient(): LoginClient {
return LoginClient(this)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,21 @@ package com.facebook.login

import android.app.Activity
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.ResolveInfo
import android.os.Bundle
import android.os.Parcel
import androidx.annotation.VisibleForTesting
import com.facebook.AccessTokenSource
import com.facebook.FacebookException
import com.facebook.FacebookSdk
import com.facebook.FacebookSdk.getExecutor
import com.facebook.FacebookServiceException
import com.facebook.internal.NativeProtocol
import com.facebook.internal.ServerProtocol.getErrorConnectionFailure
import com.facebook.internal.ServerProtocol.getErrorsProxyAuthDisabled
import com.facebook.internal.ServerProtocol.getErrorsUserCanceled
import com.facebook.internal.Utility.isNullOrEmpty
import java.lang.Exception

@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
abstract class NativeAppLoginMethodHandler : LoginMethodHandler {
Expand Down Expand Up @@ -174,17 +176,21 @@ abstract class NativeAppLoginMethodHandler : LoginMethodHandler {
}

protected open fun tryIntent(intent: Intent?, requestCode: Int): Boolean {
if (intent == null) {
return false
}
try {
loginClient.fragment?.startActivityForResult(intent, requestCode)
} catch (e: Exception) {
// We do not know if we have the activity until we try starting it.
// FB is not installed if ActivityNotFoundException is thrown and this might fallback
// to other handlers
if (intent == null || !isCallable(intent)) {
return false
}

val loginFragment = loginClient.fragment as? LoginFragment
loginFragment?.launcher?.launch(intent) ?: return false

return true
}

private fun isCallable(intent: Intent): Boolean {
val list: List<ResolveInfo> =
FacebookSdk.getApplicationContext()
.packageManager
.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
return list.isNotEmpty()
}
}

0 comments on commit 1ad14c9

Please sign in to comment.