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:
Dianne Hackborn
2014-10-10 00:30:33 +00:00
committed by Android Git Automerger
8 changed files with 170 additions and 28 deletions

View File

@@ -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;
}
}
/**

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -31,4 +31,5 @@ interface ISearchManager {
ComponentName getGlobalSearchActivity();
ComponentName getWebSearchActivity();
ComponentName getAssistIntent(int userHandle);
boolean launchAssistAction(int requestType, String hint, int userHandle);
}

View File

@@ -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;
}
}
}

View File

@@ -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

View File

@@ -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) {

View File

@@ -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);