public void AcquireToken(IDictionary <string, string> brokerPayload)
        {
            if (brokerPayload.ContainsKey(BrokerParameter.BrokerInstallUrl))
            {
                string url   = brokerPayload[BrokerParameter.BrokerInstallUrl];
                Uri    uri   = new Uri(url);
                string query = uri.Query;
                if (query.StartsWith("?"))
                {
                    query = query.Substring(1);
                }

                Dictionary <string, string> keyPair = EncodingHelper.ParseKeyValueList(query, '&', true, false, null);

                PlatformParameters pp = PlatformParameters as PlatformParameters;
                pp.CallerActivity.StartActivity(new Intent(Intent.ActionView, Android.Net.Uri.Parse(keyPair["app_link"])));

                throw new AdalException(AdalErrorAndroidEx.BrokerApplicationRequired, AdalErrorMessageAndroidEx.BrokerApplicationRequired);
            }

            Context mContext = Application.Context;
            AuthenticationRequest request        = new AuthenticationRequest(brokerPayload);
            PlatformParameters    platformParams = PlatformParameters as PlatformParameters;

            // BROKER flow intercepts here
            // cache and refresh call happens through the authenticator service
            if (mBrokerProxy.VerifyUser(request.LoginHint,
                                        request.UserId))
            {
                var msg = "It switched to broker for context: " + mContext.PackageName;
                CallState.Logger.Verbose(null, msg);
                CallState.Logger.VerbosePii(null, msg);

                request.BrokerAccountName = request.LoginHint;

                // Don't send background request, if prompt flag is always or
                // refresh_session
                bool hasAccountNameOrUserId = !string.IsNullOrEmpty(request.BrokerAccountName) || !string.IsNullOrEmpty(request.UserId);
                if (string.IsNullOrEmpty(request.Claims) && hasAccountNameOrUserId)
                {
                    msg = "User is specified for background token request";
                    CallState.Logger.Verbose(null, msg);
                    CallState.Logger.VerbosePii(null, msg);

                    resultEx = mBrokerProxy.GetAuthTokenInBackground(request, platformParams.CallerActivity);
                }
                else
                {
                    msg = "User is not specified for background token request";
                    CallState.Logger.Verbose(null, msg);
                    CallState.Logger.VerbosePii(null, msg);
                }

                if (resultEx != null && resultEx.Result != null && !string.IsNullOrEmpty(resultEx.Result.AccessToken))
                {
                    msg = "Token is returned from background call";
                    CallState.Logger.Verbose(null, msg);
                    CallState.Logger.VerbosePii(null, msg);

                    readyForResponse.Release();
                    return;
                }

                // Launch broker activity
                // if cache and refresh request is not handled.
                // Initial request to authenticator needs to launch activity to
                // record calling uid for the account. This happens for Prompt auto
                // or always behavior.
                msg = "Token is not returned from backgroud call";
                CallState.Logger.Verbose(null, msg);
                CallState.Logger.VerbosePii(null, msg);

                // Only happens with callback since silent call does not show UI
                msg = "Launch activity for Authenticator";
                CallState.Logger.Verbose(null, msg);
                CallState.Logger.VerbosePii(null, msg);

                msg = "Starting Authentication Activity";
                CallState.Logger.Verbose(null, msg);
                CallState.Logger.VerbosePii(null, msg);

                if (resultEx == null)
                {
                    msg = "Initial request to authenticator";
                    CallState.Logger.Verbose(null, msg);
                    CallState.Logger.VerbosePii(null, msg);
                    // Log the initial request but not force a prompt
                }

                if (brokerPayload.ContainsKey(BrokerParameter.SilentBrokerFlow))
                {
                    throw new AdalSilentTokenAcquisitionException();
                }

                // onActivityResult will receive the response
                // Activity needs to launch to record calling app for this
                // account
                Intent brokerIntent = mBrokerProxy.GetIntentForBrokerActivity(request, platformParams.CallerActivity);
                if (brokerIntent != null)
                {
                    try
                    {
                        msg = "Calling activity pid:" + Android.OS.Process.MyPid()
                              + " tid:" + Android.OS.Process.MyTid() + "uid:"
                              + Android.OS.Process.MyUid();
                        CallState.Logger.Verbose(null, msg);
                        CallState.Logger.VerbosePii(null, msg);

                        platformParams.CallerActivity.StartActivityForResult(brokerIntent, 1001);
                    }
                    catch (ActivityNotFoundException e)
                    {
                        CallState.Logger.Error(null, e);
                        CallState.Logger.ErrorPii(null, e);
                    }
                }
            }
            else
            {
                throw new AdalException(AdalErrorAndroidEx.NoBrokerAccountFound, "Add requested account as a Workplace account via Settings->Accounts or set UseBroker=true.");
            }
        }
        public AuthenticationResultEx GetAuthTokenInBackground(AuthenticationRequest request, Activity callerActivity)
        {
            AuthenticationResultEx authResult = null;

            VerifyNotOnMainThread();

            // if there is not any user added to account, it returns empty
            Account targetAccount = null;

            Account[] accountList = mAcctManager
                                    .GetAccountsByType(BrokerConstants.BrokerAccountType);

            if (!string.IsNullOrEmpty(request.BrokerAccountName))
            {
                targetAccount = FindAccount(request.BrokerAccountName, accountList);
            }
            else
            {
                try
                {
                    UserInfo[] users        = GetBrokerUsers();
                    UserInfo   matchingUser = FindUserInfo(request.UserId, users);
                    if (matchingUser != null)
                    {
                        targetAccount = FindAccount(matchingUser.DisplayableId, accountList);
                    }
                }
                catch (Exception e)
                {
                    CallState.Logger.Error(null, e);
                    CallState.Logger.ErrorPii(null, e);
                }
            }

            if (targetAccount != null)
            {
                Bundle brokerOptions = GetBrokerOptions(request);

                // blocking call to get token from cache or refresh request in
                // background at Authenticator
                IAccountManagerFuture result = null;
                string msg;
                try
                {
                    // It does not expect activity to be launched.
                    // AuthenticatorService is handling the request at
                    // AccountManager.
                    //
                    result = mAcctManager.GetAuthToken(targetAccount,
                                                       BrokerConstants.AuthtokenType, brokerOptions, false,
                                                       null /*
                                                             * set to null to avoid callback
                                                             */, new Handler(callerActivity.MainLooper));

                    // Making blocking request here
                    msg = "Received result from Authenticator";
                    CallState.Logger.Verbose(null, msg);
                    CallState.Logger.VerbosePii(null, msg);

                    Bundle bundleResult = (Bundle)result.GetResult(10000, TimeUnit.Milliseconds);
                    // Authenticator should throw OperationCanceledException if
                    // token is not available
                    authResult = GetResultFromBrokerResponse(bundleResult);
                }
                catch (OperationCanceledException e)
                {
                    CallState.Logger.Error(null, e);
                    CallState.Logger.ErrorPii(null, e);
                }
                catch (AuthenticatorException e)
                {
                    CallState.Logger.Error(null, e);
                    CallState.Logger.ErrorPii(null, e);
                }
                catch (Exception e)
                {
                    // Authenticator gets problem from webrequest or file read/write

                    /*                    Logger.e(TAG, "Authenticator cancels the request", "",
                     *                          ADALError.BROKER_AUTHENTICATOR_IO_EXCEPTION);*/

                    CallState.Logger.Error(null, e);
                    CallState.Logger.ErrorPii(null, e);
                }
                msg = "Returning result from Authenticator";
                CallState.Logger.Verbose(null, msg);
                CallState.Logger.VerbosePii(null, msg);

                return(authResult);
            }
            else
            {
                var msg = "Target account is not found";
                CallState.Logger.Verbose(null, msg);
                CallState.Logger.VerbosePii(null, msg);
            }

            return(null);
        }