Merge "Fix GpsLocationProvider.enable/disable/isEnabled"
diff --git a/api/current.txt b/api/current.txt
index d367a00..81e5d4f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -57,6 +57,7 @@
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
field public static final java.lang.String GET_TASKS = "android.permission.GET_TASKS";
+ field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST";
field public static final java.lang.String INJECT_EVENTS = "android.permission.INJECT_EVENTS";
@@ -2738,6 +2739,7 @@
method public void onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder);
method public boolean onPrepareOptionsMenu(android.view.Menu);
method public boolean onPreparePanel(int, android.view.View, android.view.Menu);
+ method public void onProvideAssistData(android.os.Bundle);
method protected void onRestart();
method protected void onRestoreInstanceState(android.os.Bundle);
method protected void onResume();
@@ -3077,7 +3079,9 @@
method public void onTerminate();
method public void onTrimMemory(int);
method public void registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks);
+ method public void registerOnProvideAssistData(android.app.Application.OnProvideAssistData);
method public void unregisterActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks);
+ method public void unregisterOnProvideAssistData(android.app.Application.OnProvideAssistData);
}
public static abstract interface Application.ActivityLifecycleCallbacks {
@@ -3090,6 +3094,10 @@
method public abstract void onActivityStopped(android.app.Activity);
}
+ public static abstract interface Application.OnProvideAssistData {
+ method public abstract void onProvideAssistData(android.app.Activity, android.os.Bundle);
+ }
+
public class ApplicationErrorReport implements android.os.Parcelable {
ctor public ApplicationErrorReport();
method public int describeContents();
@@ -5901,6 +5909,8 @@
field public static final android.os.Parcelable.Creator CREATOR;
field public static final java.lang.String EXTRA_ALARM_COUNT = "android.intent.extra.ALARM_COUNT";
field public static final deprecated java.lang.String EXTRA_ALLOW_REPLACE = "android.intent.extra.ALLOW_REPLACE";
+ field public static final java.lang.String EXTRA_ASSIST_CONTEXT = "android.intent.extra.ASSIST_CONTEXT";
+ field public static final java.lang.String EXTRA_ASSIST_PACKAGE = "android.intent.extra.ASSIST_PACKAGE";
field public static final java.lang.String EXTRA_BCC = "android.intent.extra.BCC";
field public static final java.lang.String EXTRA_BUG_REPORT = "android.intent.extra.BUG_REPORT";
field public static final java.lang.String EXTRA_CC = "android.intent.extra.CC";
@@ -6627,6 +6637,7 @@
method public abstract void verifyPendingInstall(int, int);
field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0
field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2
+ field public static final int COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED = 4; // 0x4
field public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; // 0x3
field public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; // 0x1
field public static final int DONT_KILL_APP = 1; // 0x1
@@ -6673,6 +6684,7 @@
field public static final int GET_ACTIVITIES = 1; // 0x1
field public static final int GET_CONFIGURATIONS = 16384; // 0x4000
field public static final int GET_DISABLED_COMPONENTS = 512; // 0x200
+ field public static final int GET_DISABLED_UNTIL_USED_COMPONENTS = 32768; // 0x8000
field public static final int GET_GIDS = 256; // 0x100
field public static final int GET_INSTRUMENTATION = 16; // 0x10
field public static final int GET_INTENT_FILTERS = 32; // 0x20
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 39539b4..f0e3370 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -135,6 +135,11 @@
return;
}
+ if ("disable-until-used".equals(op)) {
+ runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED);
+ return;
+ }
+
if ("grant".equals(op)) {
runGrantRevokePermission(true);
return;
@@ -1178,6 +1183,8 @@
return "disabled";
case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
return "disabled-user";
+ case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED:
+ return "disabled-until-used";
}
return "unknown";
}
@@ -1459,6 +1466,7 @@
System.err.println(" pm enable [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm disable [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm disable-user [--user USER_ID] PACKAGE_OR_COMPONENT");
+ System.err.println(" pm disable-until-used [--user USER_ID] PACKAGE_OR_COMPONENT");
System.err.println(" pm grant PACKAGE PERMISSION");
System.err.println(" pm revoke PACKAGE PERMISSION");
System.err.println(" pm set-install-location [0/auto] [1/internal] [2/external]");
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 2337790..3602fc4 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -132,6 +132,12 @@
public static final int DISPLAY_SHOW_CUSTOM = 0x10;
/**
+ * Allow the title to wrap onto multiple lines if space is available
+ * @hide pending API approval
+ */
+ public static final int DISPLAY_TITLE_MULTIPLE_LINES = 0x20;
+
+ /**
* Set the action bar into custom navigation mode, supplying a view
* for custom navigation.
*
@@ -680,6 +686,15 @@
public Context getThemedContext() { return null; }
/**
+ * Returns true if the Title field has been truncated during layout for lack
+ * of available space.
+ *
+ * @return true if the Title field has been truncated
+ * @hide pending API approval
+ */
+ public boolean isTitleTruncated() { return false; }
+
+ /**
* Listener interface for ActionBar navigation events.
*/
public interface OnNavigationListener {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index d6ddeb65..18ccd53 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1346,6 +1346,20 @@
}
/**
+ * This is called when the user is requesting an assist, to build a full
+ * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
+ * application. You can override this method to place into the bundle anything
+ * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
+ * of the assist Intent. The default implementation does nothing.
+ *
+ * <p>This function will be called after any global assist callbacks that had
+ * been registered with {@link Application#registerOnProvideAssistData
+ * Application.registerOnProvideAssistData}.
+ */
+ public void onProvideAssistData(Bundle data) {
+ }
+
+ /**
* Called when you are no longer visible to the user. You will next
* receive either {@link #onRestart}, {@link #onDestroy}, or nothing,
* depending on later user activity.
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 61b2067..bc27a57d 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1818,6 +1818,24 @@
return true;
}
+ case GET_TOP_ACTIVITY_EXTRAS_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ int requestType = data.readInt();
+ Bundle res = getTopActivityExtras(requestType);
+ reply.writeNoException();
+ reply.writeBundle(res);
+ return true;
+ }
+
+ case REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ Bundle extras = data.readBundle();
+ reportTopActivityExtras(token, extras);
+ reply.writeNoException();
+ return true;
+ }
+
}
return super.onTransact(code, data, reply, flags);
@@ -4149,5 +4167,30 @@
return res;
}
+ public Bundle getTopActivityExtras(int requestType) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeInt(requestType);
+ mRemote.transact(GET_TOP_ACTIVITY_EXTRAS_TRANSACTION, data, reply, 0);
+ reply.readException();
+ Bundle res = reply.readBundle();
+ data.recycle();
+ reply.recycle();
+ return res;
+ }
+
+ public void reportTopActivityExtras(IBinder token, Bundle extras) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(token);
+ data.writeBundle(extras);
+ mRemote.transact(REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
private IBinder mRemote;
}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 12716456..570fb80 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -533,6 +533,12 @@
String pkg;
CompatibilityInfo info;
}
+
+ static final class RequestActivityExtras {
+ IBinder activityToken;
+ IBinder requestToken;
+ int requestType;
+ }
private native void dumpGraphicsInfo(FileDescriptor fd);
@@ -1108,6 +1114,16 @@
queueOrSendMessage(H.UNSTABLE_PROVIDER_DIED, provider);
}
+ @Override
+ public void requestActivityExtras(IBinder activityToken, IBinder requestToken,
+ int requestType) {
+ RequestActivityExtras cmd = new RequestActivityExtras();
+ cmd.activityToken = activityToken;
+ cmd.requestToken = requestToken;
+ cmd.requestType = requestType;
+ queueOrSendMessage(H.REQUEST_ACTIVITY_EXTRAS, cmd);
+ }
+
private void printRow(PrintWriter pw, String format, Object...objs) {
pw.println(String.format(format, objs));
}
@@ -1173,6 +1189,7 @@
public static final int TRIM_MEMORY = 140;
public static final int DUMP_PROVIDER = 141;
public static final int UNSTABLE_PROVIDER_DIED = 142;
+ public static final int REQUEST_ACTIVITY_EXTRAS = 143;
String codeToString(int code) {
if (DEBUG_MESSAGES) {
switch (code) {
@@ -1219,6 +1236,7 @@
case TRIM_MEMORY: return "TRIM_MEMORY";
case DUMP_PROVIDER: return "DUMP_PROVIDER";
case UNSTABLE_PROVIDER_DIED: return "UNSTABLE_PROVIDER_DIED";
+ case REQUEST_ACTIVITY_EXTRAS: return "REQUEST_ACTIVITY_EXTRAS";
}
}
return Integer.toString(code);
@@ -1430,6 +1448,9 @@
case UNSTABLE_PROVIDER_DIED:
handleUnstableProviderDied((IBinder)msg.obj, false);
break;
+ case REQUEST_ACTIVITY_EXTRAS:
+ handleRequestActivityExtras((RequestActivityExtras)msg.obj);
+ break;
}
if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + codeToString(msg.what));
}
@@ -2322,6 +2343,23 @@
performNewIntents(data.token, data.intents);
}
+ public void handleRequestActivityExtras(RequestActivityExtras cmd) {
+ Bundle data = new Bundle();
+ ActivityClientRecord r = mActivities.get(cmd.activityToken);
+ if (r != null) {
+ r.activity.getApplication().dispatchOnProvideAssistData(r.activity, data);
+ r.activity.onProvideAssistData(data);
+ }
+ if (data.isEmpty()) {
+ data = null;
+ }
+ IActivityManager mgr = ActivityManagerNative.getDefault();
+ try {
+ mgr.reportTopActivityExtras(cmd.requestToken, data);
+ } catch (RemoteException e) {
+ }
+ }
+
private static final ThreadLocal<Intent> sCurrentBroadcastIntent = new ThreadLocal<Intent>();
/**
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 3a67cec..132388e 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -22,6 +22,7 @@
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.ContextWrapper;
+import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
@@ -45,6 +46,7 @@
new ArrayList<ComponentCallbacks>();
private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
new ArrayList<ActivityLifecycleCallbacks>();
+ private ArrayList<OnProvideAssistData> mAssistCallbacks = null;
/** @hide */
public LoadedApk mLoadedApk;
@@ -59,6 +61,21 @@
void onActivityDestroyed(Activity activity);
}
+ /**
+ * Callback interface for use with {@link Application#registerOnProvideAssistData}
+ * and {@link Application#unregisterOnProvideAssistData}.
+ */
+ public interface OnProvideAssistData {
+ /**
+ * This is called when the user is requesting an assist, to build a full
+ * {@link Intent#ACTION_ASSIST} Intent with all of the context of the current
+ * application. You can override this method to place into the bundle anything
+ * you would like to appear in the {@link Intent#EXTRA_ASSIST_CONTEXT} part
+ * of the assist Intent.
+ */
+ public void onProvideAssistData(Activity activity, Bundle data);
+ }
+
public Application() {
super(null);
}
@@ -137,7 +154,24 @@
mActivityLifecycleCallbacks.remove(callback);
}
}
-
+
+ public void registerOnProvideAssistData(OnProvideAssistData callback) {
+ synchronized (this) {
+ if (mAssistCallbacks == null) {
+ mAssistCallbacks = new ArrayList<OnProvideAssistData>();
+ }
+ mAssistCallbacks.add(callback);
+ }
+ }
+
+ public void unregisterOnProvideAssistData(OnProvideAssistData callback) {
+ synchronized (this) {
+ if (mAssistCallbacks != null) {
+ mAssistCallbacks.remove(callback);
+ }
+ }
+ }
+
// ------------------ Internal API ------------------
/**
@@ -232,4 +266,19 @@
}
return callbacks;
}
+
+ /* package */ void dispatchOnProvideAssistData(Activity activity, Bundle data) {
+ Object[] callbacks;
+ synchronized (this) {
+ if (mAssistCallbacks == null) {
+ return;
+ }
+ callbacks = mAssistCallbacks.toArray();
+ }
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((OnProvideAssistData)callbacks[i]).onProvideAssistData(activity, data);
+ }
+ }
+ }
}
diff --git a/core/java/android/app/ApplicationThreadNative.java b/core/java/android/app/ApplicationThreadNative.java
index 63aa5f9..f0e367c 100644
--- a/core/java/android/app/ApplicationThreadNative.java
+++ b/core/java/android/app/ApplicationThreadNative.java
@@ -587,6 +587,17 @@
reply.writeNoException();
return true;
}
+
+ case REQUEST_ACTIVITY_EXTRAS_TRANSACTION:
+ {
+ data.enforceInterface(IApplicationThread.descriptor);
+ IBinder activityToken = data.readStrongBinder();
+ IBinder requestToken = data.readStrongBinder();
+ int requestType = data.readInt();
+ requestActivityExtras(activityToken, requestToken, requestType);
+ reply.writeNoException();
+ return true;
+ }
}
return super.onTransact(code, data, reply, flags);
@@ -1185,4 +1196,15 @@
mRemote.transact(UNSTABLE_PROVIDER_DIED_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
data.recycle();
}
+
+ public void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ data.writeInterfaceToken(IApplicationThread.descriptor);
+ data.writeStrongBinder(activityToken);
+ data.writeStrongBinder(requestToken);
+ data.writeInt(requestType);
+ mRemote.transact(REQUEST_ACTIVITY_EXTRAS_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
+ data.recycle();
+ }
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 8af17a4..baac07f 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -368,6 +368,10 @@
public long inputDispatchingTimedOut(int pid, boolean aboveSystem) throws RemoteException;
+ public Bundle getTopActivityExtras(int requestType) throws RemoteException;
+
+ public void reportTopActivityExtras(IBinder token, Bundle extras) throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -624,4 +628,6 @@
int INPUT_DISPATCHING_TIMED_OUT_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+158;
int CLEAR_PENDING_BACKUP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+159;
int GET_INTENT_FOR_INTENT_SENDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+160;
+ int GET_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+161;
+ int REPORT_TOP_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+162;
}
diff --git a/core/java/android/app/IApplicationThread.java b/core/java/android/app/IApplicationThread.java
index 03a26d4..8516694 100644
--- a/core/java/android/app/IApplicationThread.java
+++ b/core/java/android/app/IApplicationThread.java
@@ -130,6 +130,8 @@
void dumpGfxInfo(FileDescriptor fd, String[] args) throws RemoteException;
void dumpDbInfo(FileDescriptor fd, String[] args) throws RemoteException;
void unstableProviderDied(IBinder provider) throws RemoteException;
+ void requestActivityExtras(IBinder activityToken, IBinder requestToken, int requestType)
+ throws RemoteException;
String descriptor = "android.app.IApplicationThread";
@@ -179,4 +181,5 @@
int DUMP_PROVIDER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+44;
int DUMP_DB_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+45;
int UNSTABLE_PROVIDER_DIED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+46;
+ int REQUEST_ACTIVITY_EXTRAS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+47;
}
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index 6382cee..7dfc589f 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -846,8 +846,8 @@
*
* @hide
*/
- public Intent getAssistIntent(Context context) {
- return getAssistIntent(context, UserHandle.myUserId());
+ public Intent getAssistIntent(Context context, boolean inclContext) {
+ return getAssistIntent(context, inclContext, UserHandle.myUserId());
}
/**
@@ -856,7 +856,7 @@
*
* @hide
*/
- public Intent getAssistIntent(Context context, int userHandle) {
+ public Intent getAssistIntent(Context context, boolean inclContext, int userHandle) {
try {
if (mService == null) {
return null;
@@ -867,6 +867,13 @@
}
Intent intent = new Intent(Intent.ACTION_ASSIST);
intent.setComponent(comp);
+ if (inclContext) {
+ IActivityManager am = ActivityManagerNative.getDefault();
+ Bundle extras = am.getTopActivityExtras(0);
+ if (extras != null) {
+ intent.replaceExtras(extras);
+ }
+ }
return intent;
} catch (RemoteException re) {
Log.e(TAG, "getAssistIntent() failed: " + re);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 89b1bbd..dc367dd 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1140,14 +1140,33 @@
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_WEB_SEARCH = "android.intent.action.WEB_SEARCH";
+
/**
* Activity Action: Perform assist action.
* <p>
- * Input: nothing
+ * Input: {@link #EXTRA_ASSIST_PACKAGE} and {@link #EXTRA_ASSIST_CONTEXT} can provide
+ * additional optional contextual information about where the user was when they requested
+ * the assist.
* Output: nothing.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_ASSIST = "android.intent.action.ASSIST";
+
+ /**
+ * An optional field on {@link #ACTION_ASSIST} containing the name of the current
+ * foreground application package at the time the assist was invoked.
+ */
+ public static final String EXTRA_ASSIST_PACKAGE
+ = "android.intent.extra.ASSIST_PACKAGE";
+
+ /**
+ * An optional field on {@link #ACTION_ASSIST} containing additional contextual
+ * information supplied by the current foreground app at the time of the assist
+ * request. This is a {@link Bundle} of additional data.
+ */
+ public static final String EXTRA_ASSIST_CONTEXT
+ = "android.intent.extra.ASSIST_CONTEXT";
+
/**
* Activity Action: List all available applications
* <p>Input: Nothing.
@@ -1588,7 +1607,7 @@
* <ul>
* <li> {@link #EXTRA_UID} containing the integer uid assigned to the package.
* <li> {@link #EXTRA_CHANGED_COMPONENT_NAME_LIST} containing the class name
- * of the changed components.
+ * of the changed components (or the package name itself).
* <li> {@link #EXTRA_DONT_KILL_APP} containing boolean field to override the
* default action of restarting the application.
* </ul>
@@ -2969,7 +2988,9 @@
/**
* This field is part of {@link android.content.Intent#ACTION_PACKAGE_CHANGED},
- * and contains a string array of all of the components that have changed.
+ * and contains a string array of all of the components that have changed. If
+ * the state of the overall package has changed, then it will contain an entry
+ * with the package name itself.
*/
public static final String EXTRA_CHANGED_COMPONENT_NAME_LIST =
"android.intent.extra.changed_component_name_list";
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a69f220..d80598c 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -175,6 +175,14 @@
public static final int GET_CONFIGURATIONS = 0x00004000;
/**
+ * {@link PackageInfo} flag: include disabled components which are in
+ * that state only because of {@link #COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED}
+ * in the returned info. Note that if you set this flag, applications
+ * that are in this disabled state will be reported as enabled.
+ */
+ public static final int GET_DISABLED_UNTIL_USED_COMPONENTS = 0x00008000;
+
+ /**
* Resolution and querying flag: if set, only filters that support the
* {@link android.content.Intent#CATEGORY_DEFAULT} will be considered for
* matching. This is a synonym for including the CATEGORY_DEFAULT in your
@@ -265,6 +273,19 @@
public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3;
/**
+ * Flag for {@link #setApplicationEnabledSetting(String, int, int)} only: This
+ * application should be considered, until the point where the user actually
+ * wants to use it. This means that it will not normally show up to the user
+ * (such as in the launcher), but various parts of the user interface can
+ * use {@link #GET_DISABLED_UNTIL_USED_COMPONENTS} to still see it and allow
+ * the user to select it (as for example an IME, device admin, etc). Such code,
+ * once the user has selected the app, should at that point also make it enabled.
+ * This option currently <strong>can not</strong> be used with
+ * {@link #setComponentEnabledSetting(ComponentName, int, int)}.
+ */
+ public static final int COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED = 4;
+
+ /**
* Flag parameter for {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} to
* indicate that this package should be installed as forward locked, i.e. only the app itself
* should have access to its code and non-resource assets.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 3e8c2a8..e1887bc 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3527,29 +3527,45 @@
return generateApplicationInfo(p, flags, state, UserHandle.getCallingUserId());
}
+ private static void updateApplicationInfo(ApplicationInfo ai, int flags,
+ PackageUserState state) {
+ // CompatibilityMode is global state.
+ if (!sCompatibilityModeEnabled) {
+ ai.disableCompatibilityMode();
+ }
+ if (state.installed) {
+ ai.flags |= ApplicationInfo.FLAG_INSTALLED;
+ } else {
+ ai.flags &= ~ApplicationInfo.FLAG_INSTALLED;
+ }
+ if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
+ ai.enabled = true;
+ } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
+ ai.enabled = (flags&PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0;
+ } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+ || state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
+ ai.enabled = false;
+ }
+ ai.enabledSetting = state.enabled;
+ }
+
public static ApplicationInfo generateApplicationInfo(Package p, int flags,
PackageUserState state, int userId) {
if (p == null) return null;
if (!checkUseInstalled(flags, state)) {
return null;
}
- if (!copyNeeded(flags, p, state, null, userId)) {
- // CompatibilityMode is global state. It's safe to modify the instance
- // of the package.
- if (!sCompatibilityModeEnabled) {
- p.applicationInfo.disableCompatibilityMode();
- }
- // Make sure we report as installed. Also safe to do, since the
- // default state should be installed (we will always copy if we
- // need to report it is not installed).
- p.applicationInfo.flags |= ApplicationInfo.FLAG_INSTALLED;
- if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
- p.applicationInfo.enabled = true;
- } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
- || state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
- p.applicationInfo.enabled = false;
- }
- p.applicationInfo.enabledSetting = state.enabled;
+ if (!copyNeeded(flags, p, state, null, userId)
+ && ((flags&PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) == 0
+ || state.enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
+ // In this case it is safe to directly modify the internal ApplicationInfo state:
+ // - CompatibilityMode is global state, so will be the same for every call.
+ // - We only come in to here if the app should reported as installed; this is the
+ // default state, and we will do a copy otherwise.
+ // - The enable state will always be reported the same for the application across
+ // calls; the only exception is for the UNTIL_USED mode, and in that case we will
+ // be doing a copy.
+ updateApplicationInfo(p.applicationInfo, flags, state);
return p.applicationInfo;
}
@@ -3565,26 +3581,12 @@
if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0) {
ai.sharedLibraryFiles = p.usesLibraryFiles;
}
- if (!sCompatibilityModeEnabled) {
- ai.disableCompatibilityMode();
- }
if (state.stopped) {
ai.flags |= ApplicationInfo.FLAG_STOPPED;
} else {
ai.flags &= ~ApplicationInfo.FLAG_STOPPED;
}
- if (state.installed) {
- ai.flags |= ApplicationInfo.FLAG_INSTALLED;
- } else {
- ai.flags &= ~ApplicationInfo.FLAG_INSTALLED;
- }
- if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
- ai.enabled = true;
- } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
- || state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
- ai.enabled = false;
- }
- ai.enabledSetting = state.enabled;
+ updateApplicationInfo(ai, flags, state);
return ai;
}
diff --git a/core/java/android/view/SimulatedDpad.java b/core/java/android/view/SimulatedDpad.java
index 0a37fdd..1ee416c 100644
--- a/core/java/android/view/SimulatedDpad.java
+++ b/core/java/android/view/SimulatedDpad.java
@@ -182,7 +182,7 @@
Intent intent =
((SearchManager)mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT_OR_SELF);
+ .getAssistIntent(mContext, false, UserHandle.USER_CURRENT_OR_SELF);
if (intent != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 46478ca..f041f07 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -801,6 +801,11 @@
return mThemedContext;
}
+ @Override
+ public boolean isTitleTruncated() {
+ return mActionView != null && mActionView.isTitleTruncated();
+ }
+
/**
* @hide
*/
diff --git a/core/java/com/android/internal/content/PackageMonitor.java b/core/java/com/android/internal/content/PackageMonitor.java
index 20ecace..424c19b 100644
--- a/core/java/com/android/internal/content/PackageMonitor.java
+++ b/core/java/com/android/internal/content/PackageMonitor.java
@@ -153,8 +153,33 @@
public void onPackageUpdateFinished(String packageName, int uid) {
}
-
- public void onPackageChanged(String packageName, int uid, String[] components) {
+
+ /**
+ * Direct reflection of {@link Intent#ACTION_PACKAGE_CHANGED
+ * Intent.ACTION_PACKAGE_CHANGED} being received, informing you of
+ * changes to the enabled/disabled state of components in a package
+ * and/or of the overall package.
+ *
+ * @param packageName The name of the package that is changing.
+ * @param uid The user ID the package runs under.
+ * @param components Any components in the package that are changing. If
+ * the overall package is changing, this will contain an entry of the
+ * package name itself.
+ * @return Return true to indicate you care about this change, which will
+ * result in {@link #onSomePackagesChanged()} being called later. If you
+ * return false, no further callbacks will happen about this change. The
+ * default implementation returns true if this is a change to the entire
+ * package.
+ */
+ public boolean onPackageChanged(String packageName, int uid, String[] components) {
+ if (components != null) {
+ for (String name : components) {
+ if (packageName.equals(name)) {
+ return true;
+ }
+ }
+ }
+ return false;
}
public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
@@ -189,7 +214,10 @@
*/
public void onPackageAppeared(String packageName, int reason) {
}
-
+
+ /**
+ * Called when an existing package is updated or its disabled state changes.
+ */
public void onPackageModified(String packageName) {
}
@@ -328,9 +356,10 @@
if (pkg != null) {
mModifiedPackages = mTempArray;
mTempArray[0] = pkg;
- onPackageChanged(pkg, uid, components);
- // XXX Don't want this to always cause mSomePackagesChanged,
- // since it can happen a fair amount.
+ mChangeType = PACKAGE_PERMANENT_CHANGE;
+ if (onPackageChanged(pkg, uid, components)) {
+ mSomePackagesChanged = true;
+ }
onPackageModified(pkg);
}
} else if (Intent.ACTION_QUERY_PACKAGE_RESTART.equals(action)) {
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 4d41e42..3d7e1ff 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -536,7 +536,7 @@
}
}
- private String getEnabledInputMethodsStr() {
+ public String getEnabledInputMethodsStr() {
mEnabledInputMethodsStrCache = Settings.Secure.getStringForUser(
mResolver, Settings.Secure.ENABLED_INPUT_METHODS, mCurrentUserId);
if (DEBUG) {
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 8ccc612..560227d 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -40,6 +40,7 @@
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.Layout;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
@@ -49,7 +50,6 @@
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
-import android.view.TouchDelegate;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
@@ -83,7 +83,8 @@
ActionBar.DISPLAY_USE_LOGO |
ActionBar.DISPLAY_HOME_AS_UP |
ActionBar.DISPLAY_SHOW_CUSTOM |
- ActionBar.DISPLAY_SHOW_TITLE;
+ ActionBar.DISPLAY_SHOW_TITLE |
+ ActionBar.DISPLAY_TITLE_MULTIPLE_LINES;
private static final int DEFAULT_CUSTOM_GRAVITY = Gravity.START | Gravity.CENTER_VERTICAL;
@@ -100,6 +101,7 @@
private TextView mTitleView;
private TextView mSubtitleView;
private View mTitleUpView;
+ private ViewGroup mUpGoerFive;
private Spinner mSpinner;
private LinearLayout mListNavLayout;
@@ -137,10 +139,6 @@
Window.Callback mWindowCallback;
- private final Rect mTempRect = new Rect();
- private int mMaxHomeSlop;
- private static final int MAX_HOME_SLOP = 32; // dp
-
private final AdapterView.OnItemSelectedListener mNavItemSelectedListener =
new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView parent, View view, int position, long id) {
@@ -219,9 +217,11 @@
com.android.internal.R.styleable.ActionBar_homeLayout,
com.android.internal.R.layout.action_bar_home);
- mHomeLayout = (HomeView) inflater.inflate(homeResId, this, false);
+ mUpGoerFive = (ViewGroup) inflater.inflate(
+ com.android.internal.R.layout.action_bar_up_container, this, false);
+ mHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);
- mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, this, false);
+ mExpandedHomeLayout = (HomeView) inflater.inflate(homeResId, mUpGoerFive, false);
mExpandedHomeLayout.setUp(true);
mExpandedHomeLayout.setOnClickListener(mExpandedActionViewUpListener);
mExpandedHomeLayout.setContentDescription(getResources().getText(
@@ -250,16 +250,14 @@
a.recycle();
mLogoNavItem = new ActionMenuItem(context, 0, android.R.id.home, 0, 0, mTitle);
- mHomeLayout.setOnClickListener(mUpClickListener);
- mHomeLayout.setClickable(true);
- mHomeLayout.setFocusable(true);
+
+ mUpGoerFive.setOnClickListener(mUpClickListener);
+ mUpGoerFive.setClickable(true);
+ mUpGoerFive.setFocusable(true);
if (getImportantForAccessibility() == View.IMPORTANT_FOR_ACCESSIBILITY_AUTO) {
setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
}
-
- mMaxHomeSlop =
- (int) (MAX_HOME_SLOP * context.getResources().getDisplayMetrics().density + 0.5f);
}
@Override
@@ -269,8 +267,8 @@
mTitleView = null;
mSubtitleView = null;
mTitleUpView = null;
- if (mTitleLayout != null && mTitleLayout.getParent() == this) {
- removeView(mTitleLayout);
+ if (mTitleLayout != null && mTitleLayout.getParent() == mUpGoerFive) {
+ mUpGoerFive.removeView(mTitleLayout);
}
mTitleLayout = null;
if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
@@ -551,19 +549,19 @@
}
public void setHomeButtonEnabled(boolean enable) {
- mHomeLayout.setEnabled(enable);
- mHomeLayout.setFocusable(enable);
+ mUpGoerFive.setEnabled(enable);
+ mUpGoerFive.setFocusable(enable);
// Make sure the home button has an accurate content description for accessibility.
if (!enable) {
- mHomeLayout.setContentDescription(null);
- mHomeLayout.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
+ mUpGoerFive.setContentDescription(null);
+ mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_NO);
} else {
- mHomeLayout.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO);
+ mUpGoerFive.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_AUTO);
if ((mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
- mHomeLayout.setContentDescription(mContext.getResources().getText(
+ mUpGoerFive.setContentDescription(mContext.getResources().getText(
R.string.action_bar_up_description));
} else {
- mHomeLayout.setContentDescription(mContext.getResources().getText(
+ mUpGoerFive.setContentDescription(mContext.getResources().getText(
R.string.action_bar_home_description));
}
}
@@ -600,7 +598,7 @@
if ((options & ActionBar.DISPLAY_SHOW_TITLE) != 0) {
initTitle();
} else {
- removeView(mTitleLayout);
+ mUpGoerFive.removeView(mTitleLayout);
}
}
@@ -608,8 +606,6 @@
(ActionBar.DISPLAY_HOME_AS_UP | ActionBar.DISPLAY_SHOW_HOME)) != 0) {
final boolean homeAsUp = (mDisplayOptions & ActionBar.DISPLAY_HOME_AS_UP) != 0;
mTitleUpView.setVisibility(!showHome ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE);
- mTitleLayout.setEnabled(!showHome && homeAsUp);
- mTitleLayout.setClickable(!showHome && homeAsUp);
}
if ((flagsChanged & ActionBar.DISPLAY_SHOW_CUSTOM) != 0 && mCustomNavView != null) {
@@ -620,6 +616,17 @@
}
}
+ if (mTitleLayout != null &&
+ (flagsChanged & ActionBar.DISPLAY_TITLE_MULTIPLE_LINES) != 0) {
+ if ((options & ActionBar.DISPLAY_TITLE_MULTIPLE_LINES) != 0) {
+ mTitleView.setSingleLine(false);
+ mTitleView.setMaxLines(2);
+ } else {
+ mTitleView.setMaxLines(1);
+ mTitleView.setSingleLine(true);
+ }
+ }
+
requestLayout();
} else {
invalidate();
@@ -754,7 +761,8 @@
protected void onFinishInflate() {
super.onFinishInflate();
- addView(mHomeLayout);
+ mUpGoerFive.addView(mHomeLayout, 0);
+ addView(mUpGoerFive);
if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
final ViewParent parent = mCustomNavView.getParent();
@@ -776,8 +784,6 @@
mSubtitleView = (TextView) mTitleLayout.findViewById(R.id.action_bar_subtitle);
mTitleUpView = (View) mTitleLayout.findViewById(R.id.up);
- mTitleLayout.setOnClickListener(mUpClickListener);
-
if (mTitleStyleRes != 0) {
mTitleView.setTextAppearance(mContext, mTitleStyleRes);
}
@@ -797,11 +803,9 @@
final boolean showHome = (mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0;
final boolean showTitleUp = !showHome;
mTitleUpView.setVisibility(showTitleUp ? (homeAsUp ? VISIBLE : INVISIBLE) : GONE);
- mTitleLayout.setEnabled(homeAsUp && showTitleUp);
- mTitleLayout.setClickable(homeAsUp && showTitleUp);
}
- addView(mTitleLayout);
+ mUpGoerFive.addView(mTitleLayout);
if (mExpandedActionView != null ||
(TextUtils.isEmpty(mTitle) && TextUtils.isEmpty(mSubtitle))) {
// Don't show while in expanded mode or with empty text
@@ -821,6 +825,28 @@
return mIsCollapsed;
}
+ /**
+ * @return True if any characters in the title were truncated
+ */
+ public boolean isTitleTruncated() {
+ if (mTitleView == null) {
+ return false;
+ }
+
+ final Layout titleLayout = mTitleView.getLayout();
+ if (titleLayout == null) {
+ return false;
+ }
+
+ final int lineCount = titleLayout.getLineCount();
+ for (int i = 0; i < lineCount; i++) {
+ if (titleLayout.getEllipsisCount(i) > 0) {
+ return true;
+ }
+ }
+ return false;
+ }
+
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int childCount = getChildCount();
@@ -829,7 +855,16 @@
for (int i = 0; i < childCount; i++) {
final View child = getChildAt(i);
if (child.getVisibility() != GONE &&
- !(child == mMenuView && mMenuView.getChildCount() == 0)) {
+ !(child == mMenuView && mMenuView.getChildCount() == 0) &&
+ child != mUpGoerFive) {
+ visibleChildren++;
+ }
+ }
+
+ final int upChildCount = mUpGoerFive.getChildCount();
+ for (int i = 0; i < upChildCount; i++) {
+ final View child = mUpGoerFive.getChildAt(i);
+ if (child.getVisibility() != GONE) {
visibleChildren++;
}
}
@@ -873,7 +908,8 @@
HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
- if (homeLayout.getVisibility() != GONE) {
+ int homeWidth = 0;
+ if (homeLayout.getVisibility() != GONE && homeLayout.getParent() == mUpGoerFive) {
final ViewGroup.LayoutParams lp = homeLayout.getLayoutParams();
int homeWidthSpec;
if (lp.width < 0) {
@@ -881,10 +917,18 @@
} else {
homeWidthSpec = MeasureSpec.makeMeasureSpec(lp.width, MeasureSpec.EXACTLY);
}
+
+ /*
+ * This is a little weird.
+ * We're only measuring the *home* affordance within the Up container here
+ * on purpose, because we want to give the available space to all other views before
+ * the title text. We'll remeasure the whole up container again later.
+ */
homeLayout.measure(homeWidthSpec, exactHeightSpec);
- final int homeWidth = homeLayout.getMeasuredWidth() + homeLayout.getStartOffset();
- availableWidth = Math.max(0, availableWidth - homeWidth);
- leftOfCenter = Math.max(0, availableWidth - homeWidth);
+ homeWidth = homeLayout.getMeasuredWidth();
+ final int homeOffsetWidth = homeWidth + homeLayout.getStartOffset();
+ availableWidth = Math.max(0, availableWidth - homeOffsetWidth);
+ leftOfCenter = Math.max(0, availableWidth - homeOffsetWidth);
}
if (mMenuView != null && mMenuView.getParent() == this) {
@@ -986,9 +1030,13 @@
availableWidth -= horizontalMargin + customView.getMeasuredWidth();
}
- if (mExpandedActionView == null && showTitle) {
- availableWidth = measureChildView(mTitleLayout, availableWidth,
- MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0);
+ /*
+ * Measure the whole up container now, allowing for the full home+title sections.
+ * (This will re-measure the home view.)
+ */
+ availableWidth = measureChildView(mUpGoerFive, availableWidth + homeWidth,
+ MeasureSpec.makeMeasureSpec(mContentHeight, MeasureSpec.EXACTLY), 0);
+ if (mTitleLayout != null) {
leftOfCenter = Math.max(0, leftOfCenter - mTitleLayout.getMeasuredWidth());
}
@@ -1035,25 +1083,17 @@
final int y = getPaddingTop();
HomeView homeLayout = mExpandedActionView != null ? mExpandedHomeLayout : mHomeLayout;
- boolean needsTouchDelegate = false;
- int homeSlop = mMaxHomeSlop;
- int homeRight = 0;
- if (homeLayout.getVisibility() != GONE) {
- final int startOffset = homeLayout.getStartOffset();
- x += positionChild(homeLayout,
- next(x, startOffset, isLayoutRtl), y, contentHeight, isLayoutRtl);
- x = next(x, startOffset, isLayoutRtl);
- needsTouchDelegate = homeLayout == mHomeLayout;
- homeRight = x;
- }
+ final int startOffset = homeLayout.getVisibility() != GONE &&
+ homeLayout.getParent() == mUpGoerFive ? homeLayout.getStartOffset() : 0;
+
+ // Position the up container based on where the edge of the home layout should go.
+ x += positionChild(mUpGoerFive,
+ next(x, startOffset, isLayoutRtl), y, contentHeight, isLayoutRtl);
+ x = next(x, startOffset, isLayoutRtl);
if (mExpandedActionView == null) {
final boolean showTitle = mTitleLayout != null && mTitleLayout.getVisibility() != GONE &&
(mDisplayOptions & ActionBar.DISPLAY_SHOW_TITLE) != 0;
- if (showTitle) {
- x += positionChild(mTitleLayout, x, y, contentHeight, isLayoutRtl);
- homeSlop = mTitleLayout.getWidth();
- }
switch (mNavigationMode) {
case ActionBar.NAVIGATION_MODE_STANDARD:
@@ -1063,7 +1103,6 @@
if (showTitle) {
x = next(x, mItemPadding, isLayoutRtl);
}
- homeSlop = Math.min(homeSlop, Math.max(x - homeRight, 0));
x += positionChild(mListNavLayout, x, y, contentHeight, isLayoutRtl);
x = next(x, mItemPadding, isLayoutRtl);
}
@@ -1071,7 +1110,6 @@
case ActionBar.NAVIGATION_MODE_TABS:
if (mTabScrollView != null) {
if (showTitle) x = next(x, mItemPadding, isLayoutRtl);
- homeSlop = Math.min(homeSlop, Math.max(x - homeRight, 0));
x += positionChild(mTabScrollView, x, y, contentHeight, isLayoutRtl);
x = next(x, mItemPadding, isLayoutRtl);
}
@@ -1176,7 +1214,6 @@
final int customWidth = customView.getMeasuredWidth();
customView.layout(xpos, ypos, xpos + customWidth,
ypos + customView.getMeasuredHeight());
- homeSlop = Math.min(homeSlop, Math.max(xpos - homeRight, 0));
x = next(x, customWidth, isLayoutRtl);
}
@@ -1186,14 +1223,6 @@
mProgressView.layout(mProgressBarPadding, -halfProgressHeight,
mProgressBarPadding + mProgressView.getMeasuredWidth(), halfProgressHeight);
}
-
- if (needsTouchDelegate) {
- mTempRect.set(homeLayout.getLeft(), homeLayout.getTop(),
- homeLayout.getRight() + homeSlop, homeLayout.getBottom());
- setTouchDelegate(new TouchDelegate(mTempRect, homeLayout));
- } else {
- setTouchDelegate(null);
- }
}
@Override
@@ -1493,8 +1522,8 @@
if (mExpandedActionView.getParent() != ActionBarView.this) {
addView(mExpandedActionView);
}
- if (mExpandedHomeLayout.getParent() != ActionBarView.this) {
- addView(mExpandedHomeLayout);
+ if (mExpandedHomeLayout.getParent() != mUpGoerFive) {
+ mUpGoerFive.addView(mExpandedHomeLayout);
}
mHomeLayout.setVisibility(GONE);
if (mTitleLayout != null) mTitleLayout.setVisibility(GONE);
@@ -1520,7 +1549,7 @@
}
removeView(mExpandedActionView);
- removeView(mExpandedHomeLayout);
+ mUpGoerFive.removeView(mExpandedHomeLayout);
mExpandedActionView = null;
if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) {
mHomeLayout.setVisibility(VISIBLE);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a69870b..aafc4bf 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1702,6 +1702,13 @@
android:description="@string/permdesc_stopAppSwitches"
android:protectionLevel="signature|system" />
+ <!-- Allows an application to retrieve private information about
+ the current top activity, such as any assist context it can provide. -->
+ <permission android:name="android.permission.GET_TOP_ACTIVITY_INFO"
+ android:label="@string/permlab_getTopActivityInfo"
+ android:description="@string/permdesc_getTopActivityInfo"
+ android:protectionLevel="signature" />
+
<!-- Allows an application to retrieve the current state of keys and
switches. This is only for use by the system.
@deprecated The API that used this permission has been removed. -->
diff --git a/core/res/res/layout-xlarge/screen_action_bar.xml b/core/res/res/layout-xlarge/screen_action_bar.xml
index 751d322..0b6122d 100644
--- a/core/res/res/layout-xlarge/screen_action_bar.xml
+++ b/core/res/res/layout-xlarge/screen_action_bar.xml
@@ -20,7 +20,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
- android:fitsSystemWindows="true">
+ android:fitsSystemWindows="true"
+ android:splitMotionEvents="false">
<com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout-xlarge/screen_action_bar_overlay.xml b/core/res/res/layout-xlarge/screen_action_bar_overlay.xml
index f2a1ea1..a95635e 100644
--- a/core/res/res/layout-xlarge/screen_action_bar_overlay.xml
+++ b/core/res/res/layout-xlarge/screen_action_bar_overlay.xml
@@ -23,7 +23,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/action_bar_overlay_layout"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:splitMotionEvents="false">
<FrameLayout android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git a/core/res/res/layout/action_bar_home.xml b/core/res/res/layout/action_bar_home.xml
index fe58215..5341f3d 100644
--- a/core/res/res/layout/action_bar_home.xml
+++ b/core/res/res/layout/action_bar_home.xml
@@ -17,9 +17,7 @@
<view xmlns:android="http://schemas.android.com/apk/res/android"
class="com.android.internal.widget.ActionBarView$HomeView"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:background="?android:attr/actionBarItemBackground"
- android:animateLayoutChanges="true">
+ android:layout_height="match_parent">
<ImageView android:id="@android:id/up"
android:src="?android:attr/homeAsUpIndicator"
android:layout_gravity="center_vertical|start"
diff --git a/core/res/res/layout/action_bar_title_item.xml b/core/res/res/layout/action_bar_title_item.xml
index df773eb..ccc5b07 100644
--- a/core/res/res/layout/action_bar_title_item.xml
+++ b/core/res/res/layout/action_bar_title_item.xml
@@ -16,10 +16,9 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:orientation="horizontal"
android:paddingEnd="8dip"
- android:background="?android:attr/actionBarItemBackground"
android:enabled="false">
<ImageView android:id="@android:id/up"
diff --git a/core/res/res/layout/action_bar_up_container.xml b/core/res/res/layout/action_bar_up_container.xml
new file mode 100644
index 0000000..c6fad64
--- /dev/null
+++ b/core/res/res/layout/action_bar_up_container.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2013 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:background="?android:attr/actionBarItemBackground"
+ android:gravity="center_vertical"
+ android:enabled="false">
+</LinearLayout>
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index b0f1bc5..f0b2313 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -22,7 +22,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
- android:fitsSystemWindows="true">
+ android:fitsSystemWindows="true"
+ android:splitMotionEvents="false">
<com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
diff --git a/core/res/res/layout/screen_action_bar_overlay.xml b/core/res/res/layout/screen_action_bar_overlay.xml
index 20a7db1..c8181d1 100644
--- a/core/res/res/layout/screen_action_bar_overlay.xml
+++ b/core/res/res/layout/screen_action_bar_overlay.xml
@@ -23,7 +23,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/action_bar_overlay_layout"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:splitMotionEvents="false">
<FrameLayout android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fa26089..7f0fc0b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -784,6 +784,12 @@
another app.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permlab_getTopActivityInfo">get current app info</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
+ <string name="permdesc_getTopActivityInfo">Allows the holder to retrieve private information
+ about the current application in the foreground of the screen.</string>
+
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_runSetActivityWatcher">monitor and control all app launching</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_runSetActivityWatcher">Allows the app to
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 9071440..412d4b9 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1113,6 +1113,7 @@
<java-symbol type="layout" name="keyguard_multi_user_selector_widget" />
<java-symbol type="layout" name="sms_short_code_confirmation_dialog" />
<java-symbol type="layout" name="keyguard_add_widget" />
+ <java-symbol type="layout" name="action_bar_up_container" />
<java-symbol type="anim" name="slide_in_child_bottom" />
<java-symbol type="anim" name="slide_in_right" />
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 14fe6af..b85121e 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -49,7 +49,8 @@
<uses-permission android:name="android.permission.SET_SCREEN_COMPATIBILITY" />
<uses-permission android:name="android.permission.START_ANY_ACTIVITY" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
-
+ <uses-permission android:name="android.permission.GET_TOP_ACTIVITY_INFO" />
+
<!-- WindowManager -->
<uses-permission android:name="android.permission.INTERNAL_SYSTEM_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
diff --git a/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml b/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml
new file mode 100644
index 0000000..03ca729
--- /dev/null
+++ b/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml
@@ -0,0 +1,322 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 2011, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<com.android.systemui.statusbar.phone.NavigationBarView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:background="#FF000000"
+ >
+
+ <FrameLayout android:id="@+id/rot0"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ >
+
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/nav_buttons"
+ android:animateLayoutChanges="true"
+ >
+
+ <!-- navigation controls -->
+ <View
+ android:layout_width="40dp"
+ android:layout_height="match_parent"
+ android:layout_weight="0"
+ android:visibility="invisible"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+ android:layout_width="@dimen/navigation_key_width"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_back"
+ systemui:keyCode="4"
+ android:layout_weight="0"
+ android:scaleType="center"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_back"
+ />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+ android:layout_width="@dimen/navigation_key_width"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_home"
+ systemui:keyCode="3"
+ systemui:keyRepeat="false"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_home"
+ />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
+ android:layout_width="@dimen/navigation_key_width"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_recent"
+ android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_recent"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+ android:layout_width="@dimen/navigation_menu_key_width"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_menu"
+ systemui:keyCode="82"
+ android:layout_weight="0"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_menu"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ />
+ </LinearLayout>
+
+ <!-- lights out layout to match exactly -->
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="horizontal"
+ android:id="@+id/lights_out"
+ android:visibility="gone"
+ >
+ <ImageView
+ android:layout_width="80dp"
+ android:layout_height="match_parent"
+ android:layout_marginStart="40dp"
+ android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible"
+ />
+ <ImageView
+ android:layout_width="80dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible"
+ />
+ <ImageView
+ android:layout_width="80dp"
+ android:layout_marginEnd="40dp"
+ android:layout_height="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ </LinearLayout>
+
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:layout_width="80dp"
+ android:id="@+id/search_light"
+ android:layout_height="match_parent"
+ android:layout_gravity="center_horizontal"
+ android:src="@drawable/search_light"
+ android:scaleType="center"
+ android:visibility="gone"
+ />
+
+ <com.android.systemui.statusbar.policy.DeadZone
+ android:id="@+id/deadzone"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ systemui:minSize="@dimen/navigation_bar_deadzone_size"
+ systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
+ systemui:holdTime="@integer/navigation_bar_deadzone_hold"
+ systemui:decayTime="@integer/navigation_bar_deadzone_decay"
+ systemui:orientation="horizontal"
+ android:layout_gravity="top"
+ />
+ </FrameLayout>
+
+ <FrameLayout android:id="@+id/rot90"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:visibility="gone"
+ android:paddingTop="0dp"
+ >
+
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:id="@+id/nav_buttons"
+ android:animateLayoutChanges="true"
+ >
+
+ <!-- navigation controls -->
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+ android:layout_height="40dp"
+ android:layout_width="match_parent"
+ android:src="@drawable/ic_sysbar_menu_land"
+ systemui:keyCode="82"
+ android:layout_weight="0"
+ android:visibility="invisible"
+ android:contentDescription="@string/accessibility_menu"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+ android:layout_height="80dp"
+ android:layout_width="match_parent"
+ android:src="@drawable/ic_sysbar_back_land"
+ android:scaleType="center"
+ systemui:keyCode="4"
+ android:layout_weight="0"
+ android:contentDescription="@string/accessibility_back"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ />
+ <View
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+ android:layout_height="80dp"
+ android:layout_width="match_parent"
+ android:src="@drawable/ic_sysbar_home_land"
+ systemui:keyCode="3"
+ systemui:keyRepeat="false"
+ android:layout_weight="0"
+ android:contentDescription="@string/accessibility_home"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ />
+ <View
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible"
+ />
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
+ android:layout_height="80dp"
+ android:layout_width="match_parent"
+ android:src="@drawable/ic_sysbar_recent_land"
+ android:layout_weight="0"
+ android:contentDescription="@string/accessibility_recent"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ />
+ <View
+ android:layout_height="40dp"
+ android:layout_width="match_parent"
+ android:layout_weight="0"
+ android:visibility="invisible"
+ />
+ </LinearLayout>
+
+ <!-- lights out layout to match exactly -->
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:orientation="vertical"
+ android:id="@+id/lights_out"
+ android:visibility="gone"
+ >
+ <ImageView
+ android:layout_height="80dp"
+ android:layout_marginTop="40dp"
+ android:layout_width="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ <View
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible"
+ />
+ <ImageView
+ android:layout_height="80dp"
+ android:layout_width="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_large"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ <View
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:layout_weight="1"
+ android:visibility="invisible"
+ />
+ <ImageView
+ android:layout_height="80dp"
+ android:layout_marginBottom="40dp"
+ android:layout_width="match_parent"
+ android:src="@drawable/ic_sysbar_lights_out_dot_small"
+ android:scaleType="center"
+ android:layout_weight="0"
+ />
+ </LinearLayout>
+
+ <com.android.systemui.statusbar.policy.KeyButtonView
+ android:id="@+id/search_light"
+ android:layout_height="80dp"
+ android:layout_width="match_parent"
+ android:layout_gravity="center_vertical"
+ android:src="@drawable/search_light"
+ android:scaleType="center"
+ android:visibility="gone"
+ />
+
+ <com.android.systemui.statusbar.policy.DeadZone
+ android:id="@+id/deadzone"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ systemui:minSize="@dimen/navigation_bar_deadzone_size"
+ systemui:maxSize="@dimen/navigation_bar_deadzone_size_max"
+ systemui:holdTime="@integer/navigation_bar_deadzone_hold"
+ systemui:decayTime="@integer/navigation_bar_deadzone_decay"
+ systemui:orientation="vertical"
+ android:layout_gravity="top"
+ />
+ </FrameLayout>
+
+ <!-- not used -->
+ <View android:id="@+id/rot270"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ android:visibility="gone"
+ />
+
+</com.android.systemui.statusbar.phone.NavigationBarView>
diff --git a/packages/SystemUI/res/layout/status_bar_recent_item.xml b/packages/SystemUI/res/layout/status_bar_recent_item.xml
index 7ce3a09..6290bb3 100644
--- a/packages/SystemUI/res/layout/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout/status_bar_recent_item.xml
@@ -48,6 +48,7 @@
android:ellipsize="marquee"
android:textColor="@color/status_bar_recents_app_label_color"
android:importantForAccessibility="no"
+ android:textAlignment="viewStart"
/>
<FrameLayout android:id="@+id/app_thumbnail"
android:layout_width="wrap_content"
@@ -101,6 +102,7 @@
android:layout_marginTop="3dip"
android:singleLine="true"
android:ellipsize="marquee"
+ android:textAlignment="viewStart"
/>
</RelativeLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
index c0a6f56..1f29990 100644
--- a/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/SearchPanelView.java
@@ -103,7 +103,7 @@
} else {
// Otherwise, keyguard isn't showing so launch it from here.
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT);
+ .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
if (intent == null) return;
try {
@@ -180,7 +180,7 @@
private void maybeSwapSearchIcon() {
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT);
+ .getAssistIntent(mContext, false, UserHandle.USER_CURRENT);
if (intent != null) {
ComponentName component = intent.getComponent();
if (component == null || !mGlowPadView.replaceTargetDrawablesIfPresent(component,
@@ -329,6 +329,6 @@
public boolean isAssistantAvailable() {
return ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
+ .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
}
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b5cbdd1..35ff3d6 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2206,7 +2206,7 @@
private void launchAssistAction() {
sendCloseSystemWindows(SYSTEM_DIALOG_REASON_ASSIST);
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT);
+ .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
if (intent != null) {
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_SINGLE_TOP
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index 217e5d7..27d808b 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -1567,7 +1567,7 @@
public void showAssistant() {
final Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT);
+ .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
if (intent == null) return;
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
index 76cbbd5..6859042 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardSelectorView.java
@@ -61,7 +61,7 @@
case com.android.internal.R.drawable.ic_action_assist_generic:
Intent assistIntent =
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT);
+ .getAssistIntent(mContext, true, UserHandle.USER_CURRENT);
if (assistIntent != null) {
mActivityLauncher.launchActivity(assistIntent, false, true, null, null);
} else {
@@ -195,7 +195,7 @@
currentUserHandle);
boolean searchActionAvailable =
((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
+ .getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
mCameraDisabled = cameraDisabledByAdmin || disabledBySimState || !cameraTargetPresent
|| !currentUserSetup;
mSearchDisabled = disabledBySimState || !searchActionAvailable || !searchTargetPresent
@@ -207,7 +207,7 @@
// Update the search icon with drawable from the search .apk
if (!mSearchDisabled) {
Intent intent = ((SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE))
- .getAssistIntent(mContext, UserHandle.USER_CURRENT);
+ .getAssistIntent(mContext, false, UserHandle.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
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index fef0613..8e10528 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -1428,6 +1428,6 @@
private boolean isAssistantAvailable() {
return mSearchManager != null
- && mSearchManager.getAssistIntent(mContext, UserHandle.USER_CURRENT) != null;
+ && mSearchManager.getAssistIntent(mContext, false, UserHandle.USER_CURRENT) != null;
}
}
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 593b9bf..0f14265 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -382,6 +382,8 @@
private boolean mInputBoundToKeyguard;
class SettingsObserver extends ContentObserver {
+ String mLastEnabled = "";
+
SettingsObserver(Handler handler) {
super(handler);
ContentResolver resolver = mContext.getContentResolver();
@@ -395,7 +397,13 @@
@Override public void onChange(boolean selfChange) {
synchronized (mMethodMap) {
- updateFromSettingsLocked();
+ boolean enabledChanged = false;
+ String newEnabled = mSettings.getEnabledInputMethodsStr();
+ if (!mLastEnabled.equals(newEnabled)) {
+ mLastEnabled = newEnabled;
+ enabledChanged = true;
+ }
+ updateFromSettingsLocked(enabledChanged);
}
}
}
@@ -539,7 +547,7 @@
}
if (changed) {
- updateFromSettingsLocked();
+ updateFromSettingsLocked(false);
}
}
}
@@ -674,7 +682,7 @@
}
mSettingsObserver = new SettingsObserver(mHandler);
- updateFromSettingsLocked();
+ updateFromSettingsLocked(true);
// IMMS wants to receive Intent.ACTION_LOCALE_CHANGED in order to update the current IME
// according to the new system locale.
@@ -748,7 +756,7 @@
// If the locale is changed, needs to reset the default ime
resetDefaultImeLocked(mContext);
}
- updateFromSettingsLocked();
+ updateFromSettingsLocked(true);
mLastSystemLocale = newLocale;
if (!updateOnlyWhenLocaleChanged) {
try {
@@ -1533,7 +1541,27 @@
return false;
}
- void updateFromSettingsLocked() {
+ void updateFromSettingsLocked(boolean enabledMayChange) {
+ if (enabledMayChange) {
+ List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked();
+ for (int i=0; i<enabled.size(); i++) {
+ // We allow the user to select "disabled until used" apps, so if they
+ // are enabling one of those here we now need to make it enabled.
+ InputMethodInfo imm = enabled.get(i);
+ try {
+ ApplicationInfo ai = mIPackageManager.getApplicationInfo(imm.getPackageName(),
+ PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
+ mSettings.getCurrentUserId());
+ if (ai.enabledSetting
+ == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
+ mIPackageManager.setApplicationEnabledSetting(imm.getPackageName(),
+ PackageManager.COMPONENT_ENABLED_STATE_DEFAULT,
+ PackageManager.DONT_KILL_APP, mSettings.getCurrentUserId());
+ }
+ } catch (RemoteException e) {
+ }
+ }
+ }
// We are assuming that whoever is changing DEFAULT_INPUT_METHOD and
// ENABLED_INPUT_METHODS is taking care of keeping them correctly in
// sync, so we will never have a DEFAULT_INPUT_METHOD that is not
@@ -2383,7 +2411,8 @@
final List<ResolveInfo> services = pm.queryIntentServicesAsUser(
new Intent(InputMethod.SERVICE_INTERFACE),
- PackageManager.GET_META_DATA, mSettings.getCurrentUserId());
+ PackageManager.GET_META_DATA | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS,
+ mSettings.getCurrentUserId());
final HashMap<String, List<InputMethodSubtype>> additionalSubtypes =
mFileManager.getAllAdditionalInputMethodSubtypes();
@@ -2429,7 +2458,7 @@
if (!map.containsKey(defaultImiId)) {
Slog.w(TAG, "Default IME is uninstalled. Choose new default IME.");
if (chooseNewDefaultIMELocked()) {
- updateFromSettingsLocked();
+ updateFromSettingsLocked(true);
}
} else {
// Double check that the default IME is certainly enabled.
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d8e199b..e0046ad 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -262,6 +262,9 @@
// Maximum number of users we allow to be running at a time.
static final int MAX_RUNNING_USERS = 3;
+ // How long to wait in getTopActivityExtras for the activity to respond with the result.
+ static final int PENDING_ACTIVITY_RESULT_TIMEOUT = 2*2000;
+
static final int MY_PID = Process.myPid();
static final String[] EMPTY_STRING_ARRAY = new String[0];
@@ -319,11 +322,32 @@
* Activity we have told the window manager to have key focus.
*/
ActivityRecord mFocusedActivity = null;
+
/**
* List of intents that were used to start the most recent tasks.
*/
final ArrayList<TaskRecord> mRecentTasks = new ArrayList<TaskRecord>();
+ public class PendingActivityExtras extends Binder implements Runnable {
+ public final ActivityRecord activity;
+ public boolean haveResult = false;
+ public Bundle result = null;
+ public PendingActivityExtras(ActivityRecord _activity) {
+ activity = _activity;
+ }
+ @Override
+ public void run() {
+ Slog.w(TAG, "getTopActivityExtras failed: timeout retrieving from " + activity);
+ synchronized (this) {
+ haveResult = true;
+ notifyAll();
+ }
+ }
+ }
+
+ final ArrayList<PendingActivityExtras> mPendingActivityExtras
+ = new ArrayList<PendingActivityExtras>();
+
/**
* Process management.
*/
@@ -7451,6 +7475,63 @@
return KEY_DISPATCHING_TIMEOUT;
}
+ public Bundle getTopActivityExtras(int requestType) {
+ enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
+ "getTopActivityExtras()");
+ PendingActivityExtras pae;
+ Bundle extras = new Bundle();
+ synchronized (this) {
+ ActivityRecord activity = mMainStack.mResumedActivity;
+ if (activity == null) {
+ Slog.w(TAG, "getTopActivityExtras failed: no resumed activity");
+ return null;
+ }
+ extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
+ if (activity.app == null || activity.app.thread == null) {
+ Slog.w(TAG, "getTopActivityExtras failed: no process for " + activity);
+ return extras;
+ }
+ if (activity.app.pid == Binder.getCallingPid()) {
+ Slog.w(TAG, "getTopActivityExtras failed: request process same as " + activity);
+ return extras;
+ }
+ pae = new PendingActivityExtras(activity);
+ try {
+ activity.app.thread.requestActivityExtras(activity.appToken, pae, requestType);
+ mPendingActivityExtras.add(pae);
+ mHandler.postDelayed(pae, PENDING_ACTIVITY_RESULT_TIMEOUT);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "getTopActivityExtras failed: crash calling " + activity);
+ return extras;
+ }
+ }
+ 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) {
+ mPendingActivityExtras.remove(pae);
+ mHandler.removeCallbacks(pae);
+ }
+ return extras;
+ }
+
+ public void reportTopActivityExtras(IBinder token, Bundle extras) {
+ PendingActivityExtras pae = (PendingActivityExtras)token;
+ synchronized (pae) {
+ pae.result = extras;
+ pae.haveResult = true;
+ pae.notifyAll();
+ }
+ }
+
public void registerProcessObserver(IProcessObserver observer) {
enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
"registerProcessObserver()");
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 47987f1..b893062 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -20,6 +20,7 @@
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static com.android.internal.util.ArrayUtils.appendInt;
@@ -3296,6 +3297,13 @@
Log.i(TAG, "Package " + ps.name + " at " + scanFile
+ " ignored: updated version " + ps.versionCode
+ " better than this " + pkg.mVersionCode);
+ if (!updatedPkg.codePath.equals(scanFile)) {
+ Slog.w(PackageManagerService.TAG, "Code path for hidden system pkg : "
+ + ps.name + " changing from " + updatedPkg.codePathString
+ + " to " + scanFile);
+ updatedPkg.codePath = scanFile;
+ updatedPkg.codePathString = scanFile.toString();
+ }
mLastScanError = PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
return null;
} else {
@@ -8906,13 +8914,14 @@
if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
|| newState == COMPONENT_ENABLED_STATE_ENABLED
|| newState == COMPONENT_ENABLED_STATE_DISABLED
- || newState == COMPONENT_ENABLED_STATE_DISABLED_USER)) {
+ || newState == COMPONENT_ENABLED_STATE_DISABLED_USER
+ || newState == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
throw new IllegalArgumentException("Invalid new component state: "
+ newState);
}
PackageSetting pkgSetting;
final int uid = Binder.getCallingUid();
- final int permission = mContext.checkCallingPermission(
+ final int permission = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.CHANGE_COMPONENT_ENABLED_STATE);
enforceCrossUserPermission(uid, userId, false, "set enabled");
final boolean allowedByPermission = (permission == PackageManager.PERMISSION_GRANTED);
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 06f11bc..e3365244 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -18,6 +18,7 @@
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
@@ -2412,8 +2413,14 @@
return false;
}
PackageUserState ustate = packageSettings.readUserState(userId);
+ if ((flags&PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0) {
+ if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
+ return true;
+ }
+ }
if (ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED
|| ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
+ || ustate.enabled == COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED
|| (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
&& ustate.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
return false;
diff --git a/services/java/com/android/server/usb/UsbSettingsManager.java b/services/java/com/android/server/usb/UsbSettingsManager.java
index 4b2bbfe..f9aaa17 100644
--- a/services/java/com/android/server/usb/UsbSettingsManager.java
+++ b/services/java/com/android/server/usb/UsbSettingsManager.java
@@ -364,8 +364,9 @@
}
@Override
- public void onPackageChanged(String packageName, int uid, String[] components) {
+ public boolean onPackageChanged(String packageName, int uid, String[] components) {
handlePackageUpdate(packageName);
+ return false;
}
@Override