am 0e259ce2: am 6166a824: Merge "Implement issue #17906468: Allow search request to fall back to global search" into lmp-dev
* commit '0e259ce2d7ed09c58993da5c5b63966e8f467c82': Implement issue #17906468: Allow search request to fall back to global search
This commit is contained in:
@@ -3498,14 +3498,24 @@ public class Activity extends ContextThemeWrapper
|
||||
* <p>You can override this function to force global search, e.g. in response to a dedicated
|
||||
* search key, or to block search entirely (by simply returning false).
|
||||
*
|
||||
* @return Returns {@code true} if search launched, and {@code false} if activity blocks it.
|
||||
* The default implementation always returns {@code true}.
|
||||
* <p>Note: when running in a {@link Configuration#UI_MODE_TYPE_TELEVISION}, the default
|
||||
* implementation changes to simply return false and you must supply your own custom
|
||||
* implementation if you want to support search.</p>
|
||||
*
|
||||
* @return Returns {@code true} if search launched, and {@code false} if the activity does
|
||||
* not respond to search. The default implementation always returns {@code true}, except
|
||||
* when in {@link Configuration#UI_MODE_TYPE_TELEVISION} mode where it returns false.
|
||||
*
|
||||
* @see android.app.SearchManager
|
||||
*/
|
||||
public boolean onSearchRequested() {
|
||||
startSearch(null, false, null, false);
|
||||
return true;
|
||||
if ((getResources().getConfiguration().uiMode&Configuration.UI_MODE_TYPE_MASK)
|
||||
!= Configuration.UI_MODE_TYPE_TELEVISION) {
|
||||
startSearch(null, false, null, false);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1929,7 +1929,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
case IS_INTENT_SENDER_TARGETED_TO_PACKAGE_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
IIntentSender r = IIntentSender.Stub.asInterface(
|
||||
data.readStrongBinder());
|
||||
data.readStrongBinder());
|
||||
boolean res = isIntentSenderTargetedToPackage(r);
|
||||
reply.writeNoException();
|
||||
reply.writeInt(res ? 1 : 0);
|
||||
@@ -2102,6 +2102,18 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
|
||||
return true;
|
||||
}
|
||||
|
||||
case LAUNCH_ASSIST_INTENT_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
Intent intent = Intent.CREATOR.createFromParcel(data);
|
||||
int requestType = data.readInt();
|
||||
String hint = data.readString();
|
||||
int userHandle = data.readInt();
|
||||
boolean res = launchAssistIntent(intent, requestType, hint, userHandle);
|
||||
reply.writeNoException();
|
||||
reply.writeInt(res ? 1 : 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
case KILL_UID_TRANSACTION: {
|
||||
data.enforceInterface(IActivityManager.descriptor);
|
||||
int uid = data.readInt();
|
||||
@@ -5039,6 +5051,23 @@ class ActivityManagerProxy implements IActivityManager
|
||||
reply.recycle();
|
||||
}
|
||||
|
||||
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle)
|
||||
throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
data.writeInterfaceToken(IActivityManager.descriptor);
|
||||
intent.writeToParcel(data, 0);
|
||||
data.writeInt(requestType);
|
||||
data.writeString(hint);
|
||||
data.writeInt(userHandle);
|
||||
mRemote.transact(LAUNCH_ASSIST_INTENT_TRANSACTION, data, reply, 0);
|
||||
reply.readException();
|
||||
boolean res = reply.readInt() != 0;
|
||||
data.recycle();
|
||||
reply.recycle();
|
||||
return res;
|
||||
}
|
||||
|
||||
public void killUid(int uid, String reason) throws RemoteException {
|
||||
Parcel data = Parcel.obtain();
|
||||
Parcel reply = Parcel.obtain();
|
||||
|
||||
@@ -417,6 +417,9 @@ public interface IActivityManager extends IInterface {
|
||||
|
||||
public void reportAssistContextExtras(IBinder token, Bundle extras) throws RemoteException;
|
||||
|
||||
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle)
|
||||
throws RemoteException;
|
||||
|
||||
public void killUid(int uid, String reason) throws RemoteException;
|
||||
|
||||
public void hang(IBinder who, boolean allowRestart) throws RemoteException;
|
||||
@@ -777,4 +780,5 @@ public interface IActivityManager extends IInterface {
|
||||
int RELEASE_SOME_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+236;
|
||||
int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
|
||||
int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
|
||||
int LAUNCH_ASSIST_INTENT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+239;
|
||||
}
|
||||
|
||||
@@ -31,4 +31,5 @@ interface ISearchManager {
|
||||
ComponentName getGlobalSearchActivity();
|
||||
ComponentName getWebSearchActivity();
|
||||
ComponentName getAssistIntent(int userHandle);
|
||||
boolean launchAssistAction(int requestType, String hint, int userHandle);
|
||||
}
|
||||
|
||||
@@ -989,4 +989,20 @@ public class SearchManager
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch an assist action for the current top activity.
|
||||
* @hide
|
||||
*/
|
||||
public boolean launchAssistAction(int requestType, String hint, int userHandle) {
|
||||
try {
|
||||
if (mService == null) {
|
||||
return false;
|
||||
}
|
||||
return mService.launchAssistAction(requestType, hint, userHandle);
|
||||
} catch (RemoteException re) {
|
||||
Log.e(TAG, "launchAssistAction() failed: " + re);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||
import static android.view.WindowManager.LayoutParams.*;
|
||||
|
||||
import android.app.SearchManager;
|
||||
import android.os.UserHandle;
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.view.RootViewSurfaceTaker;
|
||||
import com.android.internal.view.StandaloneActionMode;
|
||||
@@ -4004,13 +4006,21 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
|
||||
* @return true if search window opened
|
||||
*/
|
||||
private boolean launchDefaultSearch() {
|
||||
boolean result;
|
||||
final Callback cb = getCallback();
|
||||
if (cb == null || isDestroyed()) {
|
||||
return false;
|
||||
result = false;
|
||||
} else {
|
||||
sendCloseSystemWindows("search");
|
||||
return cb.onSearchRequested();
|
||||
result = cb.onSearchRequested();
|
||||
}
|
||||
if (!result && (getContext().getResources().getConfiguration().uiMode
|
||||
& Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
|
||||
// On TVs, if the app doesn't implement search, we want to launch assist.
|
||||
return ((SearchManager)getContext().getSystemService(Context.SEARCH_SERVICE))
|
||||
.launchAssistAction(0, null, UserHandle.myUserId());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -434,10 +434,19 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
|
||||
public class PendingAssistExtras extends Binder implements Runnable {
|
||||
public final ActivityRecord activity;
|
||||
public final Bundle extras;
|
||||
public final Intent intent;
|
||||
public final String hint;
|
||||
public final int userHandle;
|
||||
public boolean haveResult = false;
|
||||
public Bundle result = null;
|
||||
public PendingAssistExtras(ActivityRecord _activity) {
|
||||
public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
|
||||
String _hint, int _userHandle) {
|
||||
activity = _activity;
|
||||
extras = _extras;
|
||||
intent = _intent;
|
||||
hint = _hint;
|
||||
userHandle = _userHandle;
|
||||
}
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -10449,6 +10458,31 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
}
|
||||
|
||||
public Bundle getAssistContextExtras(int requestType) {
|
||||
PendingAssistExtras pae = enqueueAssistContext(requestType, null, null,
|
||||
UserHandle.getCallingUserId());
|
||||
if (pae == null) {
|
||||
return null;
|
||||
}
|
||||
synchronized (pae) {
|
||||
while (!pae.haveResult) {
|
||||
try {
|
||||
pae.wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
if (pae.result != null) {
|
||||
pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
|
||||
}
|
||||
}
|
||||
synchronized (this) {
|
||||
mPendingAssistExtras.remove(pae);
|
||||
mHandler.removeCallbacks(pae);
|
||||
}
|
||||
return pae.extras;
|
||||
}
|
||||
|
||||
private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
|
||||
int userHandle) {
|
||||
enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
|
||||
"getAssistContextExtras()");
|
||||
PendingAssistExtras pae;
|
||||
@@ -10462,13 +10496,13 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
|
||||
if (activity.app == null || activity.app.thread == null) {
|
||||
Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
|
||||
return extras;
|
||||
return null;
|
||||
}
|
||||
if (activity.app.pid == Binder.getCallingPid()) {
|
||||
Slog.w(TAG, "getAssistContextExtras failed: request process same as " + activity);
|
||||
return extras;
|
||||
return null;
|
||||
}
|
||||
pae = new PendingAssistExtras(activity);
|
||||
pae = new PendingAssistExtras(activity, extras, intent, hint, userHandle);
|
||||
try {
|
||||
activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
|
||||
requestType);
|
||||
@@ -10476,25 +10510,10 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
mHandler.postDelayed(pae, PENDING_ASSIST_EXTRAS_TIMEOUT);
|
||||
} catch (RemoteException e) {
|
||||
Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
|
||||
return extras;
|
||||
return null;
|
||||
}
|
||||
return pae;
|
||||
}
|
||||
synchronized (pae) {
|
||||
while (!pae.haveResult) {
|
||||
try {
|
||||
pae.wait();
|
||||
} catch (InterruptedException e) {
|
||||
}
|
||||
}
|
||||
if (pae.result != null) {
|
||||
extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, pae.result);
|
||||
}
|
||||
}
|
||||
synchronized (this) {
|
||||
mPendingAssistExtras.remove(pae);
|
||||
mHandler.removeCallbacks(pae);
|
||||
}
|
||||
return extras;
|
||||
}
|
||||
|
||||
public void reportAssistContextExtras(IBinder token, Bundle extras) {
|
||||
@@ -10503,7 +10522,38 @@ public final class ActivityManagerService extends ActivityManagerNative
|
||||
pae.result = extras;
|
||||
pae.haveResult = true;
|
||||
pae.notifyAll();
|
||||
if (pae.intent == null) {
|
||||
// Caller is just waiting for the result.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// We are now ready to launch the assist activity.
|
||||
synchronized (this) {
|
||||
boolean exists = mPendingAssistExtras.remove(pae);
|
||||
mHandler.removeCallbacks(pae);
|
||||
if (!exists) {
|
||||
// Timed out.
|
||||
return;
|
||||
}
|
||||
}
|
||||
pae.intent.replaceExtras(extras);
|
||||
if (pae.hint != null) {
|
||||
pae.intent.putExtra(pae.hint, true);
|
||||
}
|
||||
pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
closeSystemDialogs("assist");
|
||||
try {
|
||||
mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Slog.w(TAG, "No activity to handle assist action.", e);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle) {
|
||||
return enqueueAssistContext(requestType, intent, hint, userHandle) != null;
|
||||
}
|
||||
|
||||
public void registerProcessObserver(IProcessObserver observer) {
|
||||
|
||||
@@ -17,7 +17,9 @@
|
||||
package com.android.server.search;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManagerNative;
|
||||
import android.app.AppGlobals;
|
||||
import android.app.IActivityManager;
|
||||
import android.app.ISearchManager;
|
||||
import android.app.SearchManager;
|
||||
import android.app.SearchableInfo;
|
||||
@@ -32,6 +34,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.database.ContentObserver;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UserHandle;
|
||||
@@ -261,6 +264,25 @@ public class SearchManagerService extends ISearchManager.Stub {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean launchAssistAction(int requestType, String hint, int userHandle) {
|
||||
ComponentName comp = getAssistIntent(userHandle);
|
||||
if (comp == null) {
|
||||
return false;
|
||||
}
|
||||
long ident = Binder.clearCallingIdentity();
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_ASSIST);
|
||||
intent.setComponent(comp);
|
||||
IActivityManager am = ActivityManagerNative.getDefault();
|
||||
return am.launchAssistIntent(intent, requestType, hint, userHandle);
|
||||
} catch (RemoteException e) {
|
||||
} finally {
|
||||
Binder.restoreCallingIdentity(ident);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
|
||||
|
||||
Reference in New Issue
Block a user