Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c1d07a4b authored by Amith Yamasani's avatar Amith Yamasani
Browse files

Launch ASSIST intent on the current user

Lockscreen and statusbar now launch the intent on the current user.
Make sure that the intent resolution is made to the package manager
for the specific user, as the app could have been disabled for that
user or may have an alternative app installed.

Change-Id: I93b0f972d6c7e8880b146da83dc3d08a68fe7e51
parent b26295b7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -30,4 +30,5 @@ interface ISearchManager {
   List<ResolveInfo> getGlobalSearchActivities();
   ComponentName getGlobalSearchActivity();
   ComponentName getWebSearchActivity();
   ComponentName getAssistIntent(int userHandle);
}
+22 −7
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserId;
import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -845,14 +846,28 @@ public class SearchManager
     *
     * @hide
     */
    public static final Intent getAssistIntent(Context context) {
        PackageManager pm = context.getPackageManager();
    public Intent getAssistIntent(Context context) {
        return getAssistIntent(context, UserId.myUserId());
    }

    /**
     * Gets an intent for launching installed assistant activity, or null if not available.
     * @return The assist intent.
     *
     * @hide
     */
    public Intent getAssistIntent(Context context, int userHandle) {
        try {
            ComponentName comp = mService.getAssistIntent(userHandle);
            if (comp == null) {
                return null;
            }
            Intent intent = new Intent(Intent.ACTION_ASSIST);
        ComponentName component = intent.resolveActivity(pm);
        if (component != null) {
            intent.setComponent(component);
            intent.setComponent(comp);
            return intent;
        }
        } catch (RemoteException re) {
            Log.e(TAG, "getAssistIntent() failed: " + re);
            return null;
        }
    }
}
+51 −0
Original line number Diff line number Diff line
@@ -18,6 +18,9 @@ package android.server.search;

import com.android.internal.content.PackageMonitor;

import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.AppGlobals;
import android.app.ISearchManager;
import android.app.SearchManager;
import android.app.SearchableInfo;
@@ -27,14 +30,18 @@ import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.ContentObserver;
import android.os.Binder;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserId;
import android.os.UserManager;
import android.provider.Settings;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;

import java.util.List;
@@ -207,4 +214,48 @@ public class SearchManagerService extends ISearchManager.Stub {
        return getSearchables(UserId.getCallingUserId()).getWebSearchActivity();
    }

    @Override
    public ComponentName getAssistIntent(int userHandle) {
        try {
            if (userHandle != UserId.getCallingUserId()) {
                // Requesting a different user, make sure that they have the permission
                if (ActivityManager.checkComponentPermission(
                        android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
                        Binder.getCallingUid(), -1, true)
                        == PackageManager.PERMISSION_GRANTED) {
                    // Translate to the current user id, if caller wasn't aware
                    if (userHandle == UserId.USER_CURRENT) {
                        long identity = Binder.clearCallingIdentity();
                        userHandle = ActivityManagerNative.getDefault().getCurrentUser().id;
                        Binder.restoreCallingIdentity(identity);
                    }
                } else {
                    String msg = "Permission Denial: "
                            + "Request to getAssistIntent for " + userHandle
                            + " but is calling from user " + UserId.getCallingUserId()
                            + "; this requires "
                            + android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
                    Slog.w(TAG, msg);
                    return null;
                }
            }
            IPackageManager pm = AppGlobals.getPackageManager();
            Intent assistIntent = new Intent(Intent.ACTION_ASSIST);
            ResolveInfo info =
                    pm.resolveIntent(assistIntent,
                    assistIntent.resolveTypeIfNeeded(mContext.getContentResolver()),
                    PackageManager.MATCH_DEFAULT_ONLY, userHandle);
            if (info != null) {
                return new ComponentName(
                        info.activityInfo.applicationInfo.packageName,
                        info.activityInfo.name);
            }
        } catch (RemoteException re) {
            // Local call
            Log.e(TAG, "RemoteException in getAssistIntent: " + re);
        } catch (Exception e) {
            Log.e(TAG, "Exception in getAssistIntent: " + e);
        }
        return null;
    }
}
+8 −4
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.os.UserId;
import android.os.Vibrator;
import android.provider.Settings;
import android.util.AttributeSet;
@@ -73,14 +74,15 @@ public class SearchPanelView extends FrameLayout implements
        // Close Recent Apps if needed
        mBar.animateCollapse(CommandQueue.FLAG_EXCLUDE_SEARCH_PANEL);
        // Launch Assist
        Intent intent = SearchManager.getAssistIntent(mContext);
        Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
                .getAssistIntent(mContext, UserId.USER_CURRENT);
        if (intent == null) return;
        try {
            ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
                    R.anim.search_launch_enter, R.anim.search_launch_exit,
                    getHandler(), this);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            mContext.startActivity(intent, opts.toBundle());
            mContext.startActivityAsUser(intent, opts.toBundle(), UserId.USER_CURRENT);
        } catch (ActivityNotFoundException e) {
            Slog.w(TAG, "Activity not found for " + intent.getAction());
            onAnimationStarted();
@@ -140,7 +142,8 @@ public class SearchPanelView extends FrameLayout implements
    }

    private void maybeSwapSearchIcon() {
        Intent intent = SearchManager.getAssistIntent(mContext);
        Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
                .getAssistIntent(mContext, UserId.USER_CURRENT);
        if (intent != null) {
            ComponentName component = intent.getComponent();
            if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component,
@@ -277,6 +280,7 @@ public class SearchPanelView extends FrameLayout implements
    }

    public boolean isAssistantAvailable() {
        return SearchManager.getAssistIntent(mContext) != null;
        return ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
                .getAssistIntent(mContext, UserId.USER_CURRENT) != null;
    }
}
+14 −4
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.UserId;
import android.os.Vibrator;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -275,7 +276,8 @@ class LockScreen extends LinearLayout implements KeyguardScreen {

            // Update the search icon with drawable from the search .apk
            if (!mSearchDisabled) {
                Intent intent = SearchManager.getAssistIntent(mContext);
                Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
                        .getAssistIntent(mContext, UserId.USER_CURRENT);
                if (intent != null) {
                    // XXX Hack. We need to substitute the icon here but haven't formalized
                    // the public API. The "_google" metadata will be going away, so
@@ -309,7 +311,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
            final int resId = mGlowPadView.getResourceIdForTarget(target);
            switch (resId) {
                case com.android.internal.R.drawable.ic_action_assist_generic:
                    Intent assistIntent = SearchManager.getAssistIntent(mContext);
                    Intent assistIntent =
                            ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
                            .getAssistIntent(mContext, UserId.USER_CURRENT);
                    if (assistIntent != null) {
                        launchActivity(assistIntent);
                    } else {
@@ -335,6 +339,10 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
            }
        }

        /**
         * Launches the said intent for the current foreground user.
         * @param intent
         */
        private void launchActivity(Intent intent) {
            intent.setFlags(
                    Intent.FLAG_ACTIVITY_NEW_TASK
@@ -346,7 +354,7 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
                Log.w(TAG, "can't dismiss keyguard on launch");
            }
            try {
                mContext.startActivity(intent);
                mContext.startActivityAsUser(intent, UserId.USER_CURRENT);
            } catch (ActivityNotFoundException e) {
                Log.w(TAG, "Activity not found for intent + " + intent.getAction());
            }
@@ -522,7 +530,9 @@ class LockScreen extends LinearLayout implements KeyguardScreen {
        } else if (disabledBySimState) {
            Log.v(TAG, "Camera disabled by Sim State");
        }
        boolean searchActionAvailable = SearchManager.getAssistIntent(mContext) != null;
        boolean searchActionAvailable =
                ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
                .getAssistIntent(mContext, UserId.USER_CURRENT) != null;
        mCameraDisabled = disabledByAdmin || disabledBySimState || !cameraTargetPresent;
        mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent;
        mUnlockWidgetMethods.updateResources();
Loading