Categories
discuss

How does the Facebook Android App install Facebook Messenger?

I was very surprised when I found out that the Facebook app on Android apparently is able to install the Facebook Messenger app without asking for permission.
Picture

I’m aware that it is possible to install an app via another app, but the user needs to confirm the installation via a system dialog. In addition to that, on newer Android versions the user needs to give the “install from unknown sources” permission to the app that tries to make install requests.

Yet, i have not granted Facebook any install permission and there was no sysyem level dialog asking me to confirm the installation. I have also made sure that Messenger wasn’t already installed before.

Im using a Poco F2 Pro running Android 10 (Miui 12). I observed the same behaviour on different devices. What kind of magic is used by Facebook here?

Answer

If you allow it to install, and check the app settings for messenger afterwards, you’ll most likely (depending on version and device) see at the very bottom what app installed it. On my devices, it says something like this:

Facebook messenger app info screen excerpt

Now this is key: Notice that it’s not saying Google Play, nor Facebook itself. It mentions “Facebook App Installer”.

So what is this? Well, go into Settings > Apps to look for it. More than likely, you’ll find 2 apps here; “Facebook App Installer” (com.facebook.system), and “Facebook App Manager” (com.facebook.appmanager).

Now, it seems that these two apps come preinstalled on a lot of android devices (most?), and they are responsible for installing updates to the Facebook and Facebook messenger app. I haven’t decompiled these and dug into them just yet, but the fact that “Facebook App Installer” is listed as the installer of all Facebook related apps, and the fact that Facebook App Installer comes preinstalled should tell you all you need to know to answer the question here of how Facebook circumvents the permission requests to install messenger.

For the sake of completeness I’ll also mention

  • Neither of these two apps are mentioned in “Install unknown apps” (Settings > Apps > Special access > Install unknown apps).
  • Facebook App Installer doesn’t have any “dangerous” permissions listed in it’s app settings. The only permission listed is “retrieve running apps”.
  • Facebook App Manager also does not have any “dangerous” permissions listed in it’s app settings. It does have some permissions that aren’t marked as dangerous. Namely: View network connections, prevent phone from sleeping, measure app storage space, run foreground service, run at startup, have full network access, download files without notification, view Wi-Fi connections. Nothing really surprising here.

So to summarize. There’s preinstalled apps on your phone. All things related to Facebook are installed and managed through these two apps instead of through the usual channels.


Due to the nature of Facebook there’s quite a bit of speculation and hearsay essentially accusing these apps of data-collection on devices and other various nefarious purposes.

Searching for these didn’t really give me a lot of information: But they are nonetheless discussed on the following links. Please note that most of these links link to community content, and so they tend to contain a lot of Facebook paranoia and sensationalism.

https://www.facebook.com/help/android-app/812681095504818
This link is facebooks own help-page that briefly mentions these apps in passing in describing how to disable facebook app updates.

https://support.google.com/android/thread/25263840?hl=en
It’s also mentioned briefly here, on a support thread on Google Community Android Help.

https://forum.xda-developers.com/tmobile-lg-v10/help/suspicious-apps-apps-section-facebook-t3415876
Briefly talks about how to remove (seems you must root your phone to truly get rid of this). It also links to https://www.theregister.com/2018/05/22/facebook_data_leak_no_account/ which seems to speculate that these two apps collect data from device even when the Facebook app (and messenger) isn’t installed on device. Meanwhile https://thenextweb.com/finance/2019/01/09/no-samsung-isnt-pre-installing-facebook-on-your-phone/ says the reverse thing; that these two apps does not collect any information on their own.

Categories
discuss

Azure devops pipeline to build and deploy my native Android application Google Play store or App Center as App Bundle

I need to setup Azure a devops pipeline to build and deploy my native Android application to Google Play store or App Center as App Bundle.

I could figure out to deploy an apk but need help to deploy app bundle(.aab). Any help would be appreciated.

Answer

You can use the Google Play – Release Bundle task to deploy app bundle(.aab). After the Google play extension is installed in your azure devops organization. You can add Google Play – Release Bundle task in your pipeline and configure the bundleFile field to the location of the generated .aab bundleFile. See below.

- task: ms-vsclient.google-play.google-play-release-bundle.GooglePlayReleaseBundle@3
  displayName: 'Release functionParam.ps1 to internal'
  inputs:
    serviceConnection: googleServiceEndPoint
    applicationId: applicationId
    bundleFile: **/*.aab 
    

Check out below tutorial to create a pipeline for your Android application

Build, test, and deploy Android apps

Update:

You can sign aab bundle using jarsigner command in azure pipeline. You might need to use download secure file task to use your keystore_file if you upload it to secure file. For example run below jarsigner command in a powershell task:

jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 -keystore my_keystor_file.keystore -storepass 'super_secret_keystore_pass' -keypass 'super_secret_alias_password' my-app-bundle.aab myKeyStoreAlias

See this thread for more information.

You can also use Xamarin.Android build task. And pass below arguements in Additional arguments for the build to package and sign the App Bundle:

-restore -t:SignAndroidPackage -p:AndroidPackageFormat=aab -p:AndroidKeyStore=True -p:AndroidSigningKeyStore=$(keystore.secureFilePath) -p:AndroidSigningStorePass=$(KeystorePassword) -p:AndroidSigningKeyAlias=$(KeystoreAlias) -p:AndroidSigningKeyPass=$(KeystorePassword)

See here for more information.

Categories
discuss

How to use Cognito identity pool with UnAuthenticatd users in Amplify for Android

I’ve been going through the AWS Amplify docs and tutorials for how to use Amplify and Cognito identity pools together with UNauthenticated users. The example given by the Amplify docs is:

Amplify.Auth.fetchAuthSession(
    result -> {
        AWSCognitoAuthSession cognitoAuthSession = (AWSCognitoAuthSession) result;
            switch(cognitoAuthSession.getIdentityId().getType()) {
                case SUCCESS:
                    Log.i("AuthQuickStart", "IdentityId: " + cognitoAuthSession.getIdentityId().getValue());
                    break;
                case FAILURE:
                    Log.i("AuthQuickStart", "IdentityId not present because: " + cognitoAuthSession.getIdentityId().getError().toString());
            }
        },
        error -> Log.e("AuthQuickStart", error.toString())
);

But in practice when I use this code – I get an error printed out in LogCat:

AuthQuickStart: FAILURE IdentityId not present because: AmplifyException {message=You are currently signed out., cause=null, recoverySuggestion=Please sign in and reattempt the operation.}

Note: I did configure AWS Cognito to support Unauthenticaed users!

I’ve also looked everywhere for the Amplify Android API doc to see what other APIs are supported – couldn’t find any Android API docs. And looking into the AWS Amplify.Auth methods i could not find ANY function that deals with unauthenticated users

Question:

Any clue how can i use Amplify (Android) and have AWS credentials via AWS Cognito for unauthenticated users ???

Answer

This is David from the Amplify Android team. I was actually just looking into this the other day and currently there’s a hack that’s required to make unauth users work.

After setting up unauth/guest users through the CLI (as you mentioned you had) you have to call the getAWSCredentials method on the underlying escape hatch once for the app to get it to work.

Here’s a code snippet I’d written that you can run after Amplify.configure (and again, this only needs to be run once per app install):

AWSMobileClient mobileClient = (AWSMobileClient) Amplify.Auth.getPlugin("awsCognitoAuthPlugin").getEscapeHatch();

mobileClient.getAWSCredentials(new Callback<AWSCredentials>() {
     @Override
     public void onResult(AWSCredentials result) {

        // Now you'll see the Identity ID and AWSCredentials in the resulting auth session object.
        Amplify.Auth.fetchAuthSession(
            result2 -> Log.i(TAG, result2.toString()),
            error -> Log.e(TAG, error.toString()));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
     }

     @Override
     public void onError(Exception e) {
          // Handle the error however is best for your app
     }
});

I’m working on a solution to avoid this hack right now and adding a documentation section on Unauth users to our site but in the meantime this should get it working for you.

Again note you only have to do this once and from then on out, it should just work when you call fetchAuthSession.

UPDATE: The non patched (official) version:

Amplify.Auth.fetchAuthSession(
    result -> {
        AWSCognitoAuthSession cognitoAuthSession = (AWSCognitoAuthSession) result;
        switch (cognitoAuthSession.getIdentityId().getType()) {
            case SUCCESS:
                Log.i(TAG, "identity: " + cognitoAuthSession.getIdentityId().getValue());
                Log.i(TAG, "credentials: " + cognitoAuthSession.getAWSCredentials().getValue(););
                break;
            case FAILURE:
                Log.i(TAG, "FAILURE IdentityId not present because: " + cognitoAuthSession.getIdentityId().getError().toString());
        }
    },
    error -> Log.e(TAG, "UNAUTH USERS ERR: " + error.toString()));
Categories
discuss

Navigation component Kotlin – cannot be found from the current destination

I have a fragment A,B,C. Its okay when navigating from A -> B, but from B -> C it crashes.

Here is my Navigation

enter image description here

Here is my navigation code

 categoryProductItemListAdapter.setOnItemClickListener {
        val action = CategoryProductItemsDirections.actionCategoryProductItems2ToProductItem(null, it)
        navController = Navigation.findNavController(requireView())
        navController?.navigateUp()
        navController?.navigate(action)
    }

Here is the XML code for the destination to productItem

<fragment
    android:id="@+id/categoryProductItems2"
    android:name="com.sample.store.main.dashboard.ui.ui.home.categoryitems.CategoryProductItems"
    android:label="CategoryProductItems"
    tools:layout="@layout/fragment_category_product_items">
    <argument
        android:name="category_global"
        app:argType="com.sample.store.data.globalmodels.response.categories.Category" />
    <action
        android:id="@+id/action_categoryProductItems2_to_productItem"
        app:destination="@id/productItem"
        app:enterAnim="@anim/enter_from_right"
        app:exitAnim="@anim/exit_to_right"
        app:popEnterAnim="@anim/fragment_open_enter"
        app:popExitAnim="@anim/fragment_fade_exit" />
</fragment>

And here is the error:

java.lang.IllegalArgumentException: Navigation action/destination com.sample.store.full:id/action_categoryProductItems2_to_productItem cannot be found from the current destination Destination(id/navigation_home) label=Home class=com.sample.store.main.dashboard.ui.ui.home.mainui.HomeFragment

I don’t know what happened, but it seems that the navController is looking for the “navigation_home”

Answer

Firstly you should not pass requireView() when trying to retrieve your Nav controller – navController = Navigation.findNavController(requireView()). You should be passing the actual Navigation Host Fragment instance.

Secondly the issue is being caused because you are trying to call a Navigation path from B -> C, when on fragment A.

Your direction path is from B -> C

val action = CategoryProductItemsDirections.actionCategoryProductItems2ToProductItem(null, it)

But you navigate up first so you are actually now on Fragment A when trying to execute the navigation:

navController?.navigateUp()
navController?.navigate(action)
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..