summaryrefslogtreecommitdiffstats
path: root/core/java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java15
-rw-r--r--core/java/android/app/ActionBar.java14
-rw-r--r--core/java/android/app/ActivityThread.java120
-rw-r--r--core/java/android/app/Fragment.java5
-rw-r--r--core/java/android/app/FragmentManager.java2
-rw-r--r--core/java/android/content/Context.java12
-rw-r--r--core/java/android/content/Loader.java2
-rw-r--r--core/java/android/content/SyncManager.java20
-rw-r--r--core/java/android/net/VpnBuilder.java1
-rw-r--r--core/java/android/provider/ContactsContract.java33
-rw-r--r--core/java/android/view/Display.java163
-rw-r--r--core/java/android/view/DisplayList.java7
-rw-r--r--core/java/android/view/GLES20Canvas.java21
-rw-r--r--core/java/android/view/GLES20DisplayList.java6
-rw-r--r--core/java/android/view/GLES20RecordingCanvas.java2
-rw-r--r--core/java/android/view/HardwareRenderer.java70
-rw-r--r--core/java/android/view/IWindowManager.aidl1
-rw-r--r--core/java/android/view/MotionEvent.java41
-rw-r--r--core/java/android/view/View.java41
-rw-r--r--core/java/android/view/ViewDebug.java2
-rw-r--r--core/java/android/view/ViewRootImpl.java66
-rw-r--r--core/java/android/view/WindowManagerImpl.java58
-rw-r--r--core/java/android/webkit/DebugFlags.java2
-rw-r--r--core/java/android/webkit/WebTextView.java172
-rw-r--r--core/java/android/webkit/WebView.java73
-rw-r--r--core/java/android/widget/FrameLayout.java17
-rw-r--r--core/java/android/widget/SearchView.java20
-rw-r--r--core/java/com/android/internal/content/NativeLibraryHelper.java285
-rw-r--r--core/java/com/android/internal/view/menu/ActionMenuView.java22
-rw-r--r--core/java/com/android/internal/view/menu/MenuBuilder.java3
-rw-r--r--core/java/com/android/internal/view/menu/MenuItemImpl.java2
-rw-r--r--core/java/com/android/internal/widget/ActionBarView.java11
32 files changed, 578 insertions, 731 deletions
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 68c9926..1e238f0 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -130,20 +130,11 @@ import android.view.accessibility.AccessibilityNodeInfo;
* For security purposes an accessibility service can retrieve only the content of the
* currently active window. The currently active window is defined as the window from
* which was fired the last event of the following types:
- * {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_START},
- * {@link AccessibilityEvent#TYPE_TOUCH_EXPLORATION_GESTURE_END},
- * {@link AccessibilityEvent#TYPE_VIEW_CLICKED},
- * {@link AccessibilityEvent#TYPE_VIEW_FOCUSED},
+ * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED},
* {@link AccessibilityEvent#TYPE_VIEW_HOVER_ENTER},
* {@link AccessibilityEvent#TYPE_VIEW_HOVER_EXIT},
- * {@link AccessibilityEvent#TYPE_VIEW_LONG_CLICKED},
- * {@link AccessibilityEvent#TYPE_VIEW_SELECTED},
- * {@link AccessibilityEvent#TYPE_VIEW_TEXT_CHANGED},
- * {@link AccessibilityEvent#TYPE_WINDOW_STATE_CHANGED},
- * {@link AccessibilityEvent#TYPE_VIEW_SCROLLED},
- * {@link AccessibilityEvent#TYPE_VIEW_TEXT_SELECTION_CHANGED},
- * {@link AccessibilityEvent#TYPE_WINDOW_CONTENT_CHANGED}.
- * In other words, the active window is the one where the user interaction is taking place.
+ * In other words, the last window that was shown or the last window that the user has touched
+ * during touch exploration.
* </p>
* <p>
* The entry point for retrieving window content is through calling
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 36940c2..a217867 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -29,10 +29,16 @@ import android.view.Window;
import android.widget.SpinnerAdapter;
/**
- * This is the public interface to the contextual ActionBar.
- * The ActionBar acts as a replacement for the title bar in Activities.
- * It provides facilities for creating toolbar actions as well as
- * methods of navigating around an application.
+ * Acts as a replacement for the title bar in Activities.
+ * The action bar provides facilities for creating toolbar actions as well as
+ * methods of navigating the application.
+ * <p>By default, the action bar appears at the top of every activity, with the application icon on
+ * the left, followed by the activity title. Items from the activity's options menu are also
+ * accessible from the action bar.</p>
+ * <p>From your activity, you can retrieve an instance of {@link ActionBar} by calling {@link
+ * android.app.Activity#getActionBar getActionBar()}.</p>
+ * <p>For more information, read the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
+ * Bar</a> developer guide.</p>
*/
public abstract class ActionBar {
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 9bbbd6c..1e93f88 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -123,7 +123,6 @@ public final class ActivityThread {
/** @hide */
public static final String TAG = "ActivityThread";
private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
- private static final boolean DEBUG = false;
static final boolean localLOGV = false;
static final boolean DEBUG_MESSAGES = false;
/** @hide */
@@ -163,7 +162,7 @@ public final class ActivityThread {
= new ArrayList<Application>();
// set of instantiated backup agents, keyed by package name
final HashMap<String, BackupAgent> mBackupAgents = new HashMap<String, BackupAgent>();
- static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal();
+ static final ThreadLocal<ActivityThread> sThreadLocal = new ThreadLocal<ActivityThread>();
Instrumentation mInstrumentation;
String mInstrumentationAppDir = null;
String mInstrumentationAppPackage = null;
@@ -410,9 +409,9 @@ public final class ActivityThread {
CompatibilityInfo info;
}
- native private void dumpGraphicsInfo(FileDescriptor fd);
+ private native void dumpGraphicsInfo(FileDescriptor fd);
- private final class ApplicationThread extends ApplicationThreadNative {
+ private class ApplicationThread extends ApplicationThreadNative {
private static final String HEAP_COLUMN = "%13s %8s %8s %8s %8s %8s %8s";
private static final String ONE_COUNT_COLUMN = "%21s %8d";
private static final String TWO_COUNT_COLUMNS = "%21s %8d %21s %8d";
@@ -734,13 +733,13 @@ public final class ActivityThread {
FileOutputStream fout = new FileOutputStream(fd);
PrintWriter pw = new PrintWriter(fout);
try {
- return dumpMemInfo(fd, pw, args);
+ return dumpMemInfo(pw, args);
} finally {
pw.flush();
}
}
- private Debug.MemoryInfo dumpMemInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
+ private Debug.MemoryInfo dumpMemInfo(PrintWriter pw, String[] args) {
long nativeMax = Debug.getNativeHeapSize() / 1024;
long nativeAllocated = Debug.getNativeHeapAllocatedSize() / 1024;
long nativeFree = Debug.getNativeHeapFreeSize() / 1024;
@@ -754,7 +753,7 @@ public final class ActivityThread {
long dalvikFree = runtime.freeMemory() / 1024;
long dalvikAllocated = dalvikMax - dalvikFree;
long viewInstanceCount = ViewDebug.getViewInstanceCount();
- long viewRootInstanceCount = ViewDebug.getViewAncestorInstanceCount();
+ long viewRootInstanceCount = ViewDebug.getViewRootImplCount();
long appContextInstanceCount = Debug.countInstancesOfClass(ContextImpl.class);
long activityInstanceCount = Debug.countInstancesOfClass(Activity.class);
int globalAssetCount = AssetManager.getGlobalAssetCount();
@@ -868,7 +867,7 @@ public final class ActivityThread {
int otherPrivateDirty = memInfo.otherPrivateDirty;
for (int i=0; i<Debug.MemoryInfo.NUM_OTHER_STATS; i++) {
- printRow(pw, HEAP_COLUMN, memInfo.getOtherLabel(i),
+ printRow(pw, HEAP_COLUMN, Debug.MemoryInfo.getOtherLabel(i),
memInfo.getOtherPss(i), memInfo.getOtherSharedDirty(i),
memInfo.getOtherPrivateDirty(i), "", "", "");
otherPss -= memInfo.getOtherPss(i);
@@ -885,7 +884,7 @@ public final class ActivityThread {
pw.println(" ");
pw.println(" Objects");
- printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewAncestors:",
+ printRow(pw, TWO_COUNT_COLUMNS, "Views:", viewInstanceCount, "ViewRootImpl:",
viewRootInstanceCount);
printRow(pw, TWO_COUNT_COLUMNS, "AppContexts:", appContextInstanceCount,
@@ -937,6 +936,7 @@ public final class ActivityThread {
@Override
public void dumpGfxInfo(FileDescriptor fd, String[] args) {
dumpGraphicsInfo(fd);
+ WindowManagerImpl.getDefault().dumpGfxInfo(fd);
}
private void printRow(PrintWriter pw, String format, Object...objs) {
@@ -959,7 +959,7 @@ public final class ActivityThread {
}
}
- private final class H extends Handler {
+ private class H extends Handler {
public static final int LAUNCH_ACTIVITY = 100;
public static final int PAUSE_ACTIVITY = 101;
public static final int PAUSE_ACTIVITY_FINISHING= 102;
@@ -1220,7 +1220,7 @@ public final class ActivityThread {
}
}
- private final class Idler implements MessageQueue.IdleHandler {
+ private class Idler implements MessageQueue.IdleHandler {
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
if (a != null) {
@@ -1231,12 +1231,13 @@ public final class ActivityThread {
if (localLOGV) Slog.v(
TAG, "Reporting idle of " + a +
" finished=" +
- (a.activity != null ? a.activity.mFinished : false));
+ (a.activity != null && a.activity.mFinished));
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig);
a.createdConfig = null;
} catch (RemoteException ex) {
+ // Ignore
}
}
prev = a;
@@ -1256,7 +1257,7 @@ public final class ActivityThread {
}
}
- private final static class ResourcesKey {
+ private static class ResourcesKey {
final private String mResDir;
final private float mScale;
final private int mHash;
@@ -1282,17 +1283,17 @@ public final class ActivityThread {
}
}
- public static final ActivityThread currentActivityThread() {
+ public static ActivityThread currentActivityThread() {
return sThreadLocal.get();
}
- public static final String currentPackageName() {
+ public static String currentPackageName() {
ActivityThread am = currentActivityThread();
return (am != null && am.mBoundApplication != null)
? am.mBoundApplication.processName : null;
}
- public static final Application currentApplication() {
+ public static Application currentApplication() {
ActivityThread am = currentActivityThread();
return am != null ? am.mInitialApplication : null;
}
@@ -1337,7 +1338,7 @@ public final class ActivityThread {
return config;
}
- private final Configuration mMainThreadConfig = new Configuration();
+ private Configuration mMainThreadConfig = new Configuration();
Configuration applyConfigCompatMainThread(Configuration config, CompatibilityInfo compat) {
if (config == null) {
return null;
@@ -1456,6 +1457,7 @@ public final class ActivityThread {
ai = getPackageManager().getApplicationInfo(packageName,
PackageManager.GET_SHARED_LIBRARY_FILES);
} catch (RemoteException e) {
+ // Ignore
}
if (ai != null) {
@@ -1505,7 +1507,7 @@ public final class ActivityThread {
}
}
- private final LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
+ private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode) {
synchronized (mPackages) {
WeakReference<LoadedApk> ref;
@@ -1712,15 +1714,15 @@ public final class ActivityThread {
// if the thread hasn't started yet, we don't have the handler, so just
// save the messages until we're ready.
- private final void queueOrSendMessage(int what, Object obj) {
+ private void queueOrSendMessage(int what, Object obj) {
queueOrSendMessage(what, obj, 0, 0);
}
- private final void queueOrSendMessage(int what, Object obj, int arg1) {
+ private void queueOrSendMessage(int what, Object obj, int arg1) {
queueOrSendMessage(what, obj, arg1, 0);
}
- private final void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
+ private void queueOrSendMessage(int what, Object obj, int arg1, int arg2) {
synchronized (this) {
if (DEBUG_MESSAGES) Slog.v(
TAG, "SCHEDULE " + what + " " + mH.codeToString(what)
@@ -1743,7 +1745,7 @@ public final class ActivityThread {
queueOrSendMessage(H.CLEAN_UP_CONTEXT, cci);
}
- private final Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
+ private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// System.out.println("##### [" + System.currentTimeMillis() + "] ActivityThread.performLaunchActivity(" + r + ")");
ActivityInfo aInfo = r.activityInfo;
@@ -1861,7 +1863,7 @@ public final class ActivityThread {
return activity;
}
- private final void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
+ private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
@@ -1917,11 +1919,12 @@ public final class ActivityThread {
ActivityManagerNative.getDefault()
.finishActivity(r.token, Activity.RESULT_CANCELED, null);
} catch (RemoteException ex) {
+ // Ignore
}
}
}
- private final void deliverNewIntents(ActivityClientRecord r,
+ private void deliverNewIntents(ActivityClientRecord r,
List<Intent> intents) {
final int N = intents.size();
for (int i=0; i<N; i++) {
@@ -1949,7 +1952,7 @@ public final class ActivityThread {
}
}
- private final void handleNewIntent(NewIntentData data) {
+ private void handleNewIntent(NewIntentData data) {
performNewIntents(data.token, data.intents);
}
@@ -1964,7 +1967,7 @@ public final class ActivityThread {
return sCurrentBroadcastIntent.get();
}
- private final void handleReceiver(ReceiverData data) {
+ private void handleReceiver(ReceiverData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
@@ -1976,7 +1979,7 @@ public final class ActivityThread {
IActivityManager mgr = ActivityManagerNative.getDefault();
- BroadcastReceiver receiver = null;
+ BroadcastReceiver receiver;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
data.intent.setExtrasClassLoader(cl);
@@ -2026,7 +2029,7 @@ public final class ActivityThread {
}
// Instantiate a BackupAgent and tell it that it's alive
- private final void handleCreateBackupAgent(CreateBackupAgentData data) {
+ private void handleCreateBackupAgent(CreateBackupAgentData data) {
if (DEBUG_BACKUP) Slog.v(TAG, "handleCreateBackupAgent: " + data);
// no longer idle; we have backup work to do
@@ -2091,7 +2094,7 @@ public final class ActivityThread {
}
// Tear down a BackupAgent
- private final void handleDestroyBackupAgent(CreateBackupAgentData data) {
+ private void handleDestroyBackupAgent(CreateBackupAgentData data) {
if (DEBUG_BACKUP) Slog.v(TAG, "handleDestroyBackupAgent: " + data);
LoadedApk packageInfo = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
@@ -2110,7 +2113,7 @@ public final class ActivityThread {
}
}
- private final void handleCreateService(CreateServiceData data) {
+ private void handleCreateService(CreateServiceData data) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
@@ -2156,7 +2159,7 @@ public final class ActivityThread {
}
}
- private final void handleBindService(BindServiceData data) {
+ private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
@@ -2184,7 +2187,7 @@ public final class ActivityThread {
}
}
- private final void handleUnbindService(BindServiceData data) {
+ private void handleUnbindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
@@ -2236,7 +2239,7 @@ public final class ActivityThread {
}
}
- private final void handleServiceArgs(ServiceArgsData data) {
+ private void handleServiceArgs(ServiceArgsData data) {
Service s = mServices.get(data.token);
if (s != null) {
try {
@@ -2270,7 +2273,7 @@ public final class ActivityThread {
}
}
- private final void handleStopService(IBinder token) {
+ private void handleStopService(IBinder token) {
Service s = mServices.remove(token);
if (s != null) {
try {
@@ -2465,7 +2468,7 @@ public final class ActivityThread {
private Bitmap mAvailThumbnailBitmap = null;
private Canvas mThumbnailCanvas = null;
- private final Bitmap createThumbnailBitmap(ActivityClientRecord r) {
+ private Bitmap createThumbnailBitmap(ActivityClientRecord r) {
Bitmap thumbnail = mAvailThumbnailBitmap;
try {
if (thumbnail == null) {
@@ -2515,7 +2518,7 @@ public final class ActivityThread {
return thumbnail;
}
- private final void handlePauseActivity(IBinder token, boolean finished,
+ private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
@@ -2621,7 +2624,7 @@ public final class ActivityThread {
CharSequence description;
}
- private final class ProviderRefCount {
+ private class ProviderRefCount {
public int count;
ProviderRefCount(int pCount) {
count = pCount;
@@ -2636,7 +2639,7 @@ public final class ActivityThread {
* For the client, we want to call onStop()/onStart() to indicate when
* the activity's UI visibillity changes.
*/
- private final void performStopActivityInner(ActivityClientRecord r,
+ private void performStopActivityInner(ActivityClientRecord r,
StopInfo info, boolean keepShown, boolean saveState) {
if (localLOGV) Slog.v(TAG, "Performing stop of " + r);
Bundle state = null;
@@ -2699,7 +2702,7 @@ public final class ActivityThread {
}
}
- private final void updateVisibility(ActivityClientRecord r, boolean show) {
+ private void updateVisibility(ActivityClientRecord r, boolean show) {
View v = r.activity.mDecor;
if (v != null) {
if (show) {
@@ -2726,7 +2729,7 @@ public final class ActivityThread {
}
}
- private final void handleStopActivity(IBinder token, boolean show, int configChanges) {
+ private void handleStopActivity(IBinder token, boolean show, int configChanges) {
ActivityClientRecord r = mActivities.get(token);
r.activity.mConfigChangeFlags |= configChanges;
@@ -2760,7 +2763,7 @@ public final class ActivityThread {
}
}
- private final void handleWindowVisibility(IBinder token, boolean show) {
+ private void handleWindowVisibility(IBinder token, boolean show) {
ActivityClientRecord r = mActivities.get(token);
if (r == null) {
@@ -2785,7 +2788,7 @@ public final class ActivityThread {
}
}
- private final void handleSleeping(IBinder token, boolean sleeping) {
+ private void handleSleeping(IBinder token, boolean sleeping) {
ActivityClientRecord r = mActivities.get(token);
if (r == null) {
@@ -2846,7 +2849,7 @@ public final class ActivityThread {
WindowManagerImpl.getDefault().reportNewConfiguration(mConfiguration);
}
- private final void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
+ private void deliverResults(ActivityClientRecord r, List<ResultInfo> results) {
final int N = results.size();
for (int i=0; i<N; i++) {
ResultInfo ri = results.get(i);
@@ -2869,7 +2872,7 @@ public final class ActivityThread {
}
}
- private final void handleSendResult(ResultData res) {
+ private void handleSendResult(ResultData res) {
ActivityClientRecord r = mActivities.get(res.token);
if (DEBUG_RESULTS) Slog.v(TAG, "Handling send result to " + r);
if (r != null) {
@@ -2915,7 +2918,7 @@ public final class ActivityThread {
return performDestroyActivity(token, finishing, 0, false);
}
- private final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
+ private ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
ActivityClientRecord r = mActivities.get(token);
Class activityClass = null;
@@ -3008,7 +3011,7 @@ public final class ActivityThread {
return component == null ? "[Unknown]" : component.toShortString();
}
- private final void handleDestroyActivity(IBinder token, boolean finishing,
+ private void handleDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
ActivityClientRecord r = performDestroyActivity(token, finishing,
configChanges, getNonConfigInstance);
@@ -3123,7 +3126,7 @@ public final class ActivityThread {
}
}
- private final void handleRelaunchActivity(ActivityClientRecord tmp) {
+ private void handleRelaunchActivity(ActivityClientRecord tmp) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
@@ -3233,7 +3236,7 @@ public final class ActivityThread {
handleLaunchActivity(r, currentIntent);
}
- private final void handleRequestThumbnail(IBinder token) {
+ private void handleRequestThumbnail(IBinder token) {
ActivityClientRecord r = mActivities.get(token);
Bitmap thumbnail = createThumbnailBitmap(r);
CharSequence description = null;
@@ -3308,7 +3311,7 @@ public final class ActivityThread {
return callbacks;
}
- private final void performConfigurationChanged(
+ private void performConfigurationChanged(
ComponentCallbacks cb, Configuration config) {
// Only for Activity objects, check that they actually call up to their
// superclass implementation. ComponentCallbacks is an interface, so
@@ -3451,6 +3454,9 @@ public final class ActivityThread {
}
callbacks = collectComponentCallbacksLocked(false, config);
}
+
+ // Cleanup hardware accelerated stuff
+ WindowManagerImpl.getDefault().trimLocalMemory();
if (callbacks != null) {
final int N = callbacks.size();
@@ -3579,7 +3585,7 @@ public final class ActivityThread {
WindowManagerImpl.getDefault().trimMemory(level);
}
- private final void handleBindApplication(AppBindData data) {
+ private void handleBindApplication(AppBindData data) {
mBoundApplication = data;
mConfiguration = new Configuration(data.config);
mCompatConfiguration = new Configuration(data.config);
@@ -3791,7 +3797,7 @@ public final class ActivityThread {
}
}
- private final void installContentProviders(
+ private void installContentProviders(
Context context, List<ProviderInfo> providers) {
final ArrayList<IActivityManager.ContentProviderHolder> results =
new ArrayList<IActivityManager.ContentProviderHolder>();
@@ -3825,7 +3831,7 @@ public final class ActivityThread {
}
}
- private final IContentProvider getExistingProvider(Context context, String name) {
+ private IContentProvider getExistingProvider(Context context, String name) {
synchronized(mProviderMap) {
final ProviderClientRecord pr = mProviderMap.get(name);
if (pr != null) {
@@ -3835,7 +3841,7 @@ public final class ActivityThread {
}
}
- private final IContentProvider getProvider(Context context, String name) {
+ private IContentProvider getProvider(Context context, String name) {
IContentProvider existing = getExistingProvider(context, name);
if (existing != null) {
return existing;
@@ -4007,7 +4013,7 @@ public final class ActivityThread {
}
}
- private final IContentProvider installProvider(Context context,
+ private IContentProvider installProvider(Context context,
IContentProvider provider, ProviderInfo info, boolean noisy) {
ContentProvider localProvider = null;
if (provider == null) {
@@ -4027,6 +4033,7 @@ public final class ActivityThread {
c = context.createPackageContext(ai.packageName,
Context.CONTEXT_INCLUDE_CODE);
} catch (PackageManager.NameNotFoundException e) {
+ // Ignore
}
}
if (c == null) {
@@ -4086,7 +4093,7 @@ public final class ActivityThread {
return provider;
}
- private final void attach(boolean system) {
+ private void attach(boolean system) {
sThreadLocal.set(this);
mSystemThread = system;
if (!system) {
@@ -4101,6 +4108,7 @@ public final class ActivityThread {
try {
mgr.attachApplication(mAppThread);
} catch (RemoteException ex) {
+ // Ignore
}
} else {
// Don't set application object here -- if the system crashes,
@@ -4166,7 +4174,7 @@ public final class ActivityThread {
}
}
- public static final void main(String[] args) {
+ public static void main(String[] args) {
SamplingProfilerIntegration.start();
// CloseGuard defaults to true and can be quite spammy. We
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index cb97c46..e2746d4 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -162,6 +162,9 @@ final class FragmentState implements Parcelable {
* constructor to instantiate it. If the empty constructor is not available,
* a runtime exception will occur in some cases during state restore.
*
+ * <p>For more documentation, also see the <a
+ * href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+ *
* <p>Topics covered here:
* <ol>
* <li><a href="#OlderPlatforms">Older Platforms</a>
@@ -880,7 +883,7 @@ public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener
public void setHasOptionsMenu(boolean hasMenu) {
if (mHasMenu != hasMenu) {
mHasMenu = hasMenu;
- if (isAdded() && !isHidden()) {
+ if (isAdded() && !isHidden() && isResumed()) {
mActivity.invalidateOptionsMenu();
}
}
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 789d3a6..24550c5 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -978,7 +978,7 @@ final class FragmentManagerImpl extends FragmentManager {
}
}
- if (mNeedMenuInvalidate && mActivity != null) {
+ if (mNeedMenuInvalidate && mActivity != null && mCurState == Fragment.RESUMED) {
mActivity.invalidateOptionsMenu();
mNeedMenuInvalidate = false;
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index cdda910..2a02446 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -129,7 +129,7 @@ public abstract class Context {
/**
* Flag for {@link #bindService}: don't allow this binding to raise
* the target service's process to the foreground scheduling priority.
- * It will still be raised to the at least the same memory priority
+ * It will still be raised to at least the same memory priority
* as the client (so that its process will not be killable in any
* situation where the client is not killable), but for CPU scheduling
* purposes it may be left in the background. This only has an impact
@@ -138,6 +138,16 @@ public abstract class Context {
*/
public static final int BIND_NOT_FOREGROUND = 0x0004;
+ /**
+ * Flag for {@link #bindService}: allow the process hosting the bound
+ * service to go through its normal memory management. It will be
+ * treated more like a running service, allowing the system to
+ * (temporarily) expunge the process if low on memory or for some other
+ * whim it may have.
+ * @hide
+ */
+ public static final int BIND_ALLOW_OOM_MANAGEMENT = 0x0008;
+
/** Return an AssetManager instance for your application's package. */
public abstract AssetManager getAssets();
diff --git a/core/java/android/content/Loader.java b/core/java/android/content/Loader.java
index 4e70b74..368c33e 100644
--- a/core/java/android/content/Loader.java
+++ b/core/java/android/content/Loader.java
@@ -40,6 +40,8 @@ import java.io.PrintWriter;
*
* <p>Most implementations should not derive directly from this class, but
* instead inherit from {@link AsyncTaskLoader}.</p>
+ * <p>For more information, see the <a
+ * href="{@docRoot}guide/topics/fundamentals/loaders.html">Loaders</a> developer guide.</p>
*
* @param <D> The result returned when the load is complete
*/
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 2cb8a86..5be6ec1 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -1691,12 +1691,28 @@ public class SyncManager implements OnAccountsUpdateListener {
continue;
}
- // skip the sync if it isn't manual and auto sync or
- // background data usage is disabled
+ final RegisteredServicesCache.ServiceInfo<SyncAdapterType> syncAdapterInfo;
+ syncAdapterInfo = mSyncAdapters.getServiceInfo(
+ SyncAdapterType.newKey(op.authority, op.account.type));
+
+ // only proceed if network is connected for requesting UID
+ final boolean uidNetworkConnected;
+ if (syncAdapterInfo != null) {
+ final NetworkInfo networkInfo = getConnectivityManager()
+ .getActiveNetworkInfoForUid(syncAdapterInfo.uid);
+ uidNetworkConnected = networkInfo != null && networkInfo.isConnected();
+ } else {
+ uidNetworkConnected = false;
+ }
+
+ // skip the sync if it isn't manual, and auto sync or
+ // background data usage is disabled or network is
+ // disconnected for the target UID.
if (!op.extras.getBoolean(ContentResolver.SYNC_EXTRAS_IGNORE_SETTINGS, false)
&& (syncableState > 0)
&& (!masterSyncAutomatically
|| !backgroundDataUsageAllowed
+ || !uidNetworkConnected
|| !mSyncStorageEngine.getSyncAutomatically(
op.account, op.authority))) {
operationIterator.remove();
diff --git a/core/java/android/net/VpnBuilder.java b/core/java/android/net/VpnBuilder.java
index 4582523..25cedb6 100644
--- a/core/java/android/net/VpnBuilder.java
+++ b/core/java/android/net/VpnBuilder.java
@@ -91,7 +91,6 @@ import java.util.ArrayList;
*
* <p class="note">Using this class requires
* {@link android.Manifest.permission#VPN} permission.
- * @hide
*/
public class VpnBuilder {
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index b2c1386..5765dde 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -1973,6 +1973,16 @@ public final class ContactsContract {
public static final String DATA_SET = "data_set";
/**
+ * A concatenation of the account type and data set (delimited by a forward
+ * slash) - if the data set is empty, this will be the same as the account
+ * type. For applications that need to be aware of the data set, this can
+ * be used instead of account type to distinguish sets of data. This is
+ * never intended to be used for specifying accounts.
+ * @hide
+ */
+ public static final String ACCOUNT_TYPE_AND_DATA_SET = "account_type_and_data_set";
+
+ /**
* The aggregation mode for this contact.
* <P>Type: INTEGER</P>
*/
@@ -6444,6 +6454,16 @@ public final class ContactsContract {
public static final String DATA_SET = "data_set";
/**
+ * A concatenation of the account type and data set (delimited by a forward
+ * slash) - if the data set is empty, this will be the same as the account
+ * type. For applications that need to be aware of the data set, this can
+ * be used instead of account type to distinguish sets of data. This is
+ * never intended to be used for specifying accounts.
+ * @hide
+ */
+ public static final String ACCOUNT_TYPE_AND_DATA_SET = "account_type_and_data_set";
+
+ /**
* The display title of this group.
* <p>
* Type: TEXT
@@ -7871,6 +7891,19 @@ public final class ContactsContract {
* @hide
*/
public static final String ACCOUNT = "com.android.contacts.extra.ACCOUNT";
+
+ /**
+ * Used to specify the data set within the account in which to create the
+ * new contact.
+ * <p>
+ * This value is optional - if it is not specified, the contact will be
+ * created in the base account, with no data set.
+ * <p>
+ * Type: String
+ *
+ * @hide
+ */
+ public static final String DATA_SET = "com.android.contacts.extra.DATA_SET";
}
}
}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 5ab2024..d9efe0c 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -25,16 +25,18 @@ import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.util.Slog;
+/**
+ * Provides information about the display size and density.
+ */
public class Display {
static final String TAG = "Display";
static final boolean DEBUG_COMPAT = false;
/**
- * Specify the default Display
+ * The default Display id.
*/
public static final int DEFAULT_DISPLAY = 0;
-
/**
* Use {@link android.view.WindowManager#getDefaultDisplay()
* WindowManager.getDefaultDisplay()} to create a Display object.
@@ -55,16 +57,6 @@ public class Display {
init(display);
}
- /** @hide */
- public static void setCompatibilityInfo(CompatibilityInfo compatInfo) {
- if (compatInfo != null && (compatInfo.isScalingRequired()
- || !compatInfo.supportsScreen())) {
- sCompatibilityInfo = compatInfo;
- } else {
- sCompatibilityInfo = null;
- }
- }
-
/**
* Returns the index of this display. This is currently undefined; do
* not use.
@@ -80,25 +72,29 @@ public class Display {
native static int getDisplayCount();
/**
- * Returns the raw size of the display, in pixels. Note that this
- * should <em>not</em> generally be used for computing layouts, since
- * a device will typically have screen decoration (such as a status bar)
+ * Gets the size of the display, in pixels.
+ * <p>
+ * Note that this value should <em>not</em> be used for computing layouts,
+ * since a device will typically have screen decoration (such as a status bar)
* along the edges of the display that reduce the amount of application
- * space available from the raw size returned here. This value is
- * adjusted for you based on the current rotation of the display.
+ * space available from the size returned here. Layouts should instead use
+ * the window size.
+ * </p><p>
+ * The size is adjusted based on the current rotation of the display.
+ * </p><p>
+ * The size returned by this method does not necessarily represent the
+ * actual raw size (native resolution) of the display. The returned size may
+ * be adjusted to exclude certain system decor elements that are always visible.
+ * It may also be scaled to provide compatibility with older applications that
+ * were originally designed for smaller displays.
+ * </p>
+ *
+ * @param outSize A {@link Point} object to receive the size information.
*/
public void getSize(Point outSize) {
getSizeInternal(outSize, true);
}
- /**
- * Returns the raw size of the display, in pixels. Note that this
- * should <em>not</em> generally be used for computing layouts, since
- * a device will typically have screen decoration (such as a status bar)
- * along the edges of the display that reduce the amount of application
- * space available from the raw size returned here. This value is
- * adjusted for you based on the current rotation of the display.
- */
private void getSizeInternal(Point outSize, boolean doCompat) {
try {
IWindowManager wm = getWindowManager();
@@ -118,8 +114,8 @@ public class Display {
} else {
// This is just for boot-strapping, initializing the
// system process before the window manager is up.
- outSize.x = getRealWidth();
- outSize.y = getRealHeight();
+ outSize.x = getRawWidth();
+ outSize.y = getRawHeight();
}
if (DEBUG_COMPAT && doCompat) Slog.v(TAG, "Returning display size: " + outSize);
} catch (RemoteException e) {
@@ -128,7 +124,10 @@ public class Display {
}
/**
- * This is just easier for some parts of the framework.
+ * Gets the size of the display as a rectangle, in pixels.
+ *
+ * @param outSize A {@link Rect} object to receive the size information.
+ * @see #getSize(Point)
*/
public void getRectSize(Rect outSize) {
synchronized (mTmpPoint) {
@@ -182,14 +181,49 @@ public class Display {
}
}
- /** @hide Returns the actual screen size, not including any decor. */
- native public int getRealWidth();
- /** @hide Returns the actual screen size, not including any decor. */
- native public int getRealHeight();
+ /**
+ * Gets the real size of the display without subtracting any window decor or
+ * applying any compatibility scale factors.
+ * <p>
+ * The real size may be smaller than the raw size when the window manager
+ * is emulating a smaller display (using adb shell am display-size).
+ * </p><p>
+ * The size is adjusted based on the current rotation of the display.
+ * </p>
+ * @hide
+ */
+ public void getRealSize(Point outSize) {
+ try {
+ IWindowManager wm = getWindowManager();
+ if (wm != null) {
+ wm.getRealDisplaySize(outSize);
+ } else {
+ // This is just for boot-strapping, initializing the
+ // system process before the window manager is up.
+ outSize.x = getRawWidth();
+ outSize.y = getRawHeight();
+ }
+ } catch (RemoteException e) {
+ Slog.w("Display", "Unable to get real display size", e);
+ }
+ }
- /** @hide special for when we are faking the screen size. */
+ /**
+ * Gets the raw width of the display, in pixels.
+ * <p>
+ * The size is adjusted based on the current rotation of the display.
+ * </p>
+ * @hide
+ */
native public int getRawWidth();
- /** @hide special for when we are faking the screen size. */
+
+ /**
+ * Gets the raw height of the display, in pixels.
+ * <p>
+ * The size is adjusted based on the current rotation of the display.
+ * </p>
+ * @hide
+ */
native public int getRawHeight();
/**
@@ -235,17 +269,24 @@ public class Display {
}
/**
- * Initialize a DisplayMetrics object from this display's data.
- *
- * @param outMetrics
+ * Gets display metrics that describe the size and density of this display.
+ * <p>
+ * The size is adjusted based on the current rotation of the display.
+ * </p><p>
+ * The size returned by this method does not necessarily represent the
+ * actual raw size (native resolution) of the display. The returned size may
+ * be adjusted to exclude certain system decor elements that are always visible.
+ * It may also be scaled to provide compatibility with older applications that
+ * were originally designed for smaller displays.
+ * </p>
+ *
+ * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
*/
public void getMetrics(DisplayMetrics outMetrics) {
synchronized (mTmpPoint) {
getSizeInternal(mTmpPoint, false);
- outMetrics.widthPixels = mTmpPoint.x;
- outMetrics.heightPixels = mTmpPoint.y;
+ getMetricsWithSize(outMetrics, mTmpPoint.x, mTmpPoint.y);
}
- getNonSizeMetrics(outMetrics);
CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded();
if (ci != null) {
@@ -257,22 +298,44 @@ public class Display {
}
/**
- * Initialize a DisplayMetrics object from this display's data.
- *
- * @param outMetrics
+ * Gets display metrics based on the real size of this display.
* @hide
*/
public void getRealMetrics(DisplayMetrics outMetrics) {
- outMetrics.widthPixels = getRealWidth();
- outMetrics.heightPixels = getRealHeight();
- getNonSizeMetrics(outMetrics);
+ synchronized (mTmpPoint) {
+ getRealSize(mTmpPoint);
+ getMetricsWithSize(outMetrics, mTmpPoint.x, mTmpPoint.y);
+ }
+ }
+
+ /**
+ * If the display is mirrored to an external HDMI display, returns the
+ * width of that display.
+ * @hide
+ */
+ public int getRawExternalWidth() {
+ return 1280;
+ }
+
+ /**
+ * If the display is mirrored to an external HDMI display, returns the
+ * height of that display.
+ * @hide
+ */
+ public int getRawExternalHeight() {
+ return 720;
}
- private void getNonSizeMetrics(DisplayMetrics outMetrics) {
+ /**
+ * Gets display metrics based on an explicit assumed display size.
+ * @hide
+ */
+ public void getMetricsWithSize(DisplayMetrics outMetrics,
+ int width, int height) {
outMetrics.densityDpi = (int)((mDensity*DisplayMetrics.DENSITY_DEFAULT)+.5f);
- outMetrics.noncompatWidthPixels = outMetrics.widthPixels;
- outMetrics.noncompatHeightPixels = outMetrics.heightPixels;
+ outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
+ outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
outMetrics.density = outMetrics.noncompatDensity = mDensity;
outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
@@ -315,8 +378,6 @@ public class Display {
private static boolean sInitialized = false;
private static IWindowManager sWindowManager;
- private static volatile CompatibilityInfo sCompatibilityInfo;
-
/**
* Returns a display object which uses the metric's width/height instead.
* @hide
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index f4c0249..8f4ece0 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -54,4 +54,11 @@ public abstract class DisplayList {
* @return boolean true if the display list is able to be replayed, false otherwise.
*/
abstract boolean isValid();
+
+ /**
+ * Return the amount of memory used by this display list.
+ *
+ * @return The size of this display list in bytes
+ */
+ abstract int getSize();
}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index d561484..a7fe95d 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -277,14 +277,25 @@ class GLES20Canvas extends HardwareCanvas {
///////////////////////////////////////////////////////////////////////////
/**
+ * Must match Caches::FlushMode values
+ *
+ * @see #flushCaches(int)
+ */
+ public static final int FLUSH_CACHES_LAYERS = 0;
+
+ /**
+ * Must match Caches::FlushMode values
+ *
* @see #flushCaches(int)
*/
- public static final int FLUSH_CACHES_MODERATE = 0;
+ public static final int FLUSH_CACHES_MODERATE = 1;
/**
+ * Must match Caches::FlushMode values
+ *
* @see #flushCaches(int)
*/
- public static final int FLUSH_CACHES_FULL = 1;
+ public static final int FLUSH_CACHES_FULL = 2;
/**
* Flush caches to reclaim as much memory as possible. The amount of memory
@@ -319,6 +330,12 @@ class GLES20Canvas extends HardwareCanvas {
private static native void nDestroyDisplayList(int displayList);
+ static int getDisplayListSize(int displayList) {
+ return nGetDisplayListSize(displayList);
+ }
+
+ private static native int nGetDisplayListSize(int displayList);
+
@Override
public boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty) {
return nDrawDisplayList(mRenderer,
diff --git a/core/java/android/view/GLES20DisplayList.java b/core/java/android/view/GLES20DisplayList.java
index 9e649ce..4ca5e98 100644
--- a/core/java/android/view/GLES20DisplayList.java
+++ b/core/java/android/view/GLES20DisplayList.java
@@ -82,6 +82,12 @@ class GLES20DisplayList extends DisplayList {
}
}
+ @Override
+ int getSize() {
+ if (mFinalizer == null) return 0;
+ return GLES20Canvas.getDisplayListSize(mFinalizer.mNativeDisplayList);
+ }
+
private static class DisplayListFinalizer {
final int mNativeDisplayList;
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index 078222b..c987f48 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -38,7 +38,7 @@ import android.util.Pools;
class GLES20RecordingCanvas extends GLES20Canvas implements Poolable<GLES20RecordingCanvas> {
// The recording canvas pool should be large enough to handle a deeply nested
// view hierarchy because display lists are generated recursively.
- private static final int POOL_LIMIT = 50;
+ private static final int POOL_LIMIT = 25;
private static final Pool<GLES20RecordingCanvas> sPool = Pools.synchronizedPool(
Pools.finitePool(new PoolableManager<GLES20RecordingCanvas>() {
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index d2476af..4e4923b 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -140,6 +140,13 @@ public abstract class HardwareRenderer {
abstract void updateSurface(SurfaceHolder holder) throws Surface.OutOfResourcesException;
/**
+ * Destoys the layers used by the specified view hierarchy.
+ *
+ * @param view The root of the view hierarchy
+ */
+ abstract void destroyLayers(View view);
+
+ /**
* This method should be invoked whenever the current hardware renderer
* context should be reset.
*/
@@ -622,18 +629,8 @@ public abstract class HardwareRenderer {
+ "from multiple threads");
}
- /*
- * The window size has changed, so we need to create a new
- * surface.
- */
- if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
- /*
- * Unbind and destroy the old EGL surface, if
- * there is one.
- */
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
- }
+ // In case we need to destroy an existing surface
+ destroySurface();
// Create an EGL surface we can render into.
mEglSurface = sEgl.eglCreateWindowSurface(sEglDisplay, sEglConfig, holder, null);
@@ -693,15 +690,21 @@ public abstract class HardwareRenderer {
mDestroyed = true;
- sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
+ destroySurface();
- mEglSurface = null;
mGl = null;
setEnabled(false);
}
+ void destroySurface() {
+ if (mEglSurface != null && mEglSurface != EGL_NO_SURFACE) {
+ sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ sEgl.eglDestroySurface(sEglDisplay, mEglSurface);
+ mEglSurface = null;
+ }
+ }
+
@Override
void invalidate() {
// Cancels any existing buffer to ensure we'll get a buffer
@@ -921,6 +924,36 @@ public abstract class HardwareRenderer {
return ((GLES20TextureLayer) layer).getSurfaceTexture();
}
+ @Override
+ void destroyLayers(View view) {
+ if (view != null && isEnabled()) {
+ checkCurrent();
+ destroyHardwareLayer(view);
+ GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_LAYERS);
+ }
+ }
+
+ private void destroyHardwareLayer(View view) {
+ if (view.destroyLayer()) {
+ view.invalidate(true);
+ }
+ if (view instanceof ViewGroup) {
+ ViewGroup group = (ViewGroup) view;
+
+ int count = group.getChildCount();
+ for (int i = 0; i < count; i++) {
+ destroyHardwareLayer(group.getChildAt(i));
+ }
+ }
+ }
+
+ static HardwareRenderer create(boolean translucent) {
+ if (GLES20Canvas.isAvailable()) {
+ return new Gl20Renderer(translucent);
+ }
+ return null;
+ }
+
static void trimMemory(int level) {
if (sEgl == null || sEglConfig == null) return;
@@ -950,12 +983,5 @@ public abstract class HardwareRenderer {
break;
}
}
-
- static HardwareRenderer create(boolean translucent) {
- if (GLES20Canvas.isAvailable()) {
- return new Gl20Renderer(translucent);
- }
- return null;
- }
}
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index ad17edf..81cd798 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -55,6 +55,7 @@ interface IWindowManager
boolean inputMethodClientHasFocus(IInputMethodClient client);
void getDisplaySize(out Point size);
+ void getRealDisplaySize(out Point size);
int getMaximumSizeDimension();
void setForcedDisplaySize(int longDimen, int shortDimen);
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index 88f59d4..da5c7b2 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -1123,7 +1123,10 @@ public final class MotionEvent extends InputEvent implements Parcelable {
}
/**
- * Button constant: Primary button (left mouse button, stylus tip).
+ * Button constant: Primary button (left mouse button).
+ *
+ * This button constant is not set in response to simple touches with a finger
+ * or stylus tip. The user must actually push a button.
*
* @see #getButtonState
*/
@@ -1215,55 +1218,32 @@ public final class MotionEvent extends InputEvent implements Parcelable {
public static final int TOOL_TYPE_UNKNOWN = 0;
/**
- * Tool type constant: The tool is a finger directly touching the display.
- *
- * This is a <em>direct</em> positioning tool.
+ * Tool type constant: The tool is a finger.
*
* @see #getToolType
*/
public static final int TOOL_TYPE_FINGER = 1;
/**
- * Tool type constant: The tool is a stylus directly touching the display
- * or hovering slightly above it.
- *
- * This is a <em>direct</em> positioning tool.
+ * Tool type constant: The tool is a stylus.
*
* @see #getToolType
*/
public static final int TOOL_TYPE_STYLUS = 2;
/**
- * Tool type constant: The tool is a mouse or trackpad that translates
- * relative motions into cursor movements on the display.
- *
- * This is an <em>indirect</em> positioning tool.
+ * Tool type constant: The tool is a mouse or trackpad.
*
* @see #getToolType
*/
public static final int TOOL_TYPE_MOUSE = 3;
/**
- * Tool type constant: The tool is a finger on a touch pad that is not
- * directly attached to the display. Finger movements on the touch pad
- * may be translated into touches on the display, possibly with visual feedback.
- *
- * This is an <em>indirect</em> positioning tool.
- *
- * @see #getToolType
- */
- public static final int TOOL_TYPE_INDIRECT_FINGER = 4;
-
- /**
- * Tool type constant: The tool is a stylus on a digitizer tablet that is not
- * attached to the display. Stylus movements on the digitizer may be translated
- * into touches on the display, possibly with visual feedback.
- *
- * This is an <em>indirect</em> positioning tool.
+ * Tool type constant: The tool is an eraser or a stylus being used in an inverted posture.
*
* @see #getToolType
*/
- public static final int TOOL_TYPE_INDIRECT_STYLUS = 5;
+ public static final int TOOL_TYPE_ERASER = 4;
// NOTE: If you add a new tool type here you must also add it to:
// native/include/android/input.h
@@ -1276,8 +1256,7 @@ public final class MotionEvent extends InputEvent implements Parcelable {
names.append(TOOL_TYPE_FINGER, "TOOL_TYPE_FINGER");
names.append(TOOL_TYPE_STYLUS, "TOOL_TYPE_STYLUS");
names.append(TOOL_TYPE_MOUSE, "TOOL_TYPE_MOUSE");
- names.append(TOOL_TYPE_INDIRECT_FINGER, "TOOL_TYPE_INDIRECT_FINGER");
- names.append(TOOL_TYPE_INDIRECT_STYLUS, "TOOL_TYPE_INDIRECT_STYLUS");
+ names.append(TOOL_TYPE_ERASER, "TOOL_TYPE_ERASER");
}
// Private value for history pos that obtains the current sample.
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2213188..296e6be 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -672,19 +672,23 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
private static final int FITS_SYSTEM_WINDOWS = 0x00000002;
/**
- * This view is visible. Use with {@link #setVisibility(int)}.
+ * This view is visible.
+ * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
+ * android:visibility}.
*/
public static final int VISIBLE = 0x00000000;
/**
* This view is invisible, but it still takes up space for layout purposes.
- * Use with {@link #setVisibility(int)}.
+ * Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
+ * android:visibility}.
*/
public static final int INVISIBLE = 0x00000004;
/**
* This view is invisible, and it doesn't take any space for layout
- * purposes. Use with {@link #setVisibility(int)}.
+ * purposes. Use with {@link #setVisibility} and <a href="#attr_android:visibility">{@code
+ * android:visibility}.
*/
public static final int GONE = 0x00000008;
@@ -2294,8 +2298,8 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
private Bitmap mDrawingCache;
private Bitmap mUnscaledDrawingCache;
- private DisplayList mDisplayList;
private HardwareLayer mHardwareLayer;
+ DisplayList mDisplayList;
/**
* When this view has focus and the next focus is {@link #FOCUS_LEFT},
@@ -9226,10 +9230,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
destroyDrawingCache();
- if (mHardwareLayer != null) {
- mHardwareLayer.destroy();
- mHardwareLayer = null;
- }
+ destroyLayer();
if (mDisplayList != null) {
mDisplayList.invalidate();
@@ -9601,21 +9602,10 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
// Destroy any previous software drawing cache if needed
switch (mLayerType) {
case LAYER_TYPE_HARDWARE:
- if (mHardwareLayer != null) {
- mHardwareLayer.destroy();
- mHardwareLayer = null;
- }
+ destroyLayer();
// fall through - unaccelerated views may use software layer mechanism instead
case LAYER_TYPE_SOFTWARE:
- if (mDrawingCache != null) {
- mDrawingCache.recycle();
- mDrawingCache = null;
- }
-
- if (mUnscaledDrawingCache != null) {
- mUnscaledDrawingCache.recycle();
- mUnscaledDrawingCache = null;
- }
+ destroyDrawingCache();
break;
default:
break;
@@ -9741,6 +9731,15 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
return mHardwareLayer;
}
+ boolean destroyLayer() {
+ if (mHardwareLayer != null) {
+ mHardwareLayer.destroy();
+ mHardwareLayer = null;
+ return true;
+ }
+ return false;
+ }
+
/**
* <p>Enables or disables the drawing cache. When the drawing cache is enabled, the next call
* to {@link #getDrawingCache()} or {@link #buildDrawingCache()} will draw the view in a
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 4acf48c..96e550e 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -420,7 +420,7 @@ public class ViewDebug {
*
* @hide
*/
- public static long getViewAncestorInstanceCount() {
+ public static long getViewRootImplCount() {
return Debug.countInstancesOfClass(ViewRootImpl.class);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 35a40fc..9460fe5 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -80,6 +80,7 @@ import com.android.internal.view.RootViewSurfaceTaker;
import java.io.IOException;
import java.io.OutputStream;
+import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
@@ -235,7 +236,6 @@ public final class ViewRootImpl extends Handler implements ViewParent,
final Configuration mLastConfiguration = new Configuration();
final Configuration mPendingConfiguration = new Configuration();
-
class ResizedInfo {
Rect coveredInsets;
Rect visibleInsets;
@@ -541,6 +541,29 @@ public final class ViewRootImpl extends Handler implements ViewParent,
}
}
+ private void destroyHardwareResources() {
+ if (mAttachInfo.mHardwareRenderer != null) {
+ if (mAttachInfo.mHardwareRenderer.isEnabled()) {
+ mAttachInfo.mHardwareRenderer.destroyLayers(mView);
+ }
+ mAttachInfo.mHardwareRenderer.destroy(false);
+ }
+ }
+
+ void destroyHardwareLayers() {
+ if (mThread != Thread.currentThread()) {
+ if (mAttachInfo.mHardwareRenderer != null &&
+ mAttachInfo.mHardwareRenderer.isEnabled()) {
+ HardwareRenderer.trimMemory(ComponentCallbacks.TRIM_MEMORY_MODERATE);
+ }
+ } else {
+ if (mAttachInfo.mHardwareRenderer != null &&
+ mAttachInfo.mHardwareRenderer.isEnabled()) {
+ mAttachInfo.mHardwareRenderer.destroyLayers(mView);
+ }
+ }
+ }
+
private void enableHardwareAcceleration(WindowManager.LayoutParams attrs) {
mAttachInfo.mHardwareAccelerated = false;
mAttachInfo.mHardwareAccelerationRequested = false;
@@ -825,8 +848,10 @@ public final class ViewRootImpl extends Handler implements ViewParent,
if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL) {
// NOTE -- system code, won't try to do compat mode.
Display disp = WindowManagerImpl.getDefault().getDefaultDisplay();
- desiredWindowWidth = disp.getRealWidth();
- desiredWindowHeight = disp.getRealHeight();
+ Point size = new Point();
+ disp.getRealSize(size);
+ desiredWindowWidth = size.x;
+ desiredWindowHeight = size.y;
} else {
DisplayMetrics packageMetrics =
mView.getContext().getResources().getDisplayMetrics();
@@ -869,9 +894,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
attachInfo.mWindowVisibility = viewVisibility;
host.dispatchWindowVisibilityChanged(viewVisibility);
if (viewVisibility != View.VISIBLE || mNewSurfaceNeeded) {
- if (mAttachInfo.mHardwareRenderer != null) {
- mAttachInfo.mHardwareRenderer.destroy(false);
- }
+ destroyHardwareResources();
}
if (viewVisibility == View.GONE) {
// After making a window gone, we will count it as being
@@ -980,8 +1003,10 @@ public final class ViewRootImpl extends Handler implements ViewParent,
if (lp.type == WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL) {
// NOTE -- system code, won't try to do compat mode.
Display disp = WindowManagerImpl.getDefault().getDefaultDisplay();
- desiredWindowWidth = disp.getRealWidth();
- desiredWindowHeight = disp.getRealHeight();
+ Point size = new Point();
+ disp.getRealSize(size);
+ desiredWindowWidth = size.x;
+ desiredWindowHeight = size.y;
} else {
DisplayMetrics packageMetrics = res.getDisplayMetrics();
desiredWindowWidth = packageMetrics.widthPixels;
@@ -3485,6 +3510,31 @@ public final class ViewRootImpl extends Handler implements ViewParent,
public void debug() {
mView.debug();
}
+
+ public void dumpGfxInfo(PrintWriter pw, int[] info) {
+ if (mView != null) {
+ getGfxInfo(mView, info);
+ } else {
+ info[0] = info[1] = 0;
+ }
+ }
+
+ private void getGfxInfo(View view, int[] info) {
+ DisplayList displayList = view.mDisplayList;
+ info[0]++;
+ if (displayList != null) {
+ info[1] += displayList.getSize();
+ }
+
+ if (view instanceof ViewGroup) {
+ ViewGroup group = (ViewGroup) view;
+
+ int count = group.getChildCount();
+ for (int i = 0; i < count; i++) {
+ getGfxInfo(group.getChildAt(i), info);
+ }
+ }
+ }
public void die(boolean immediate) {
if (immediate) {
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index a451bb5..5ef4f3e 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -24,6 +24,9 @@ import android.util.AndroidRuntimeException;
import android.util.Log;
import android.view.inputmethod.InputMethodManager;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.PrintWriter;
import java.util.HashMap;
final class WindowLeaked extends AndroidRuntimeException {
@@ -392,7 +395,7 @@ public class WindowManagerImpl implements WindowManager {
leak.setStackTrace(root.getLocation().getStackTrace());
Log.e("WindowManager", leak.getMessage(), leak);
}
-
+
removeViewLocked(i);
i--;
count--;
@@ -410,6 +413,59 @@ public class WindowManagerImpl implements WindowManager {
}
}
+ /**
+ * @hide
+ */
+ public void trimLocalMemory() {
+ synchronized (this) {
+ if (mViews == null) return;
+ int count = mViews.length;
+ for (int i = 0; i < count; i++) {
+ mRoots[i].destroyHardwareLayers();
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public void dumpGfxInfo(FileDescriptor fd) {
+ FileOutputStream fout = new FileOutputStream(fd);
+ PrintWriter pw = new PrintWriter(fout);
+ try {
+ synchronized (this) {
+ if (mViews != null) {
+ pw.println("View hierarchy:");
+
+ final int count = mViews.length;
+
+ int viewsCount = 0;
+ int displayListsSize = 0;
+ int[] info = new int[2];
+
+ for (int i = 0; i < count; i++) {
+ ViewRootImpl root = mRoots[i];
+ root.dumpGfxInfo(pw, info);
+
+ String name = root.getClass().getName() + '@' +
+ Integer.toHexString(hashCode());
+ pw.printf(" %s: %d views, %.2f kB (display lists)\n",
+ name, info[0], info[1] / 1024.0f);
+
+ viewsCount += info[0];
+ displayListsSize += info[1];
+ }
+
+ pw.printf("\nTotal ViewRootImpl: %d\n", count);
+ pw.printf("Total Views: %d\n", viewsCount);
+ pw.printf("Total DisplayList: %.2f kB\n\n", displayListsSize / 1024.0f);
+ }
+ }
+ } finally {
+ pw.flush();
+ }
+ }
+
public void setStoppedState(IBinder token, boolean stopped) {
synchronized (this) {
if (mViews == null)
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index 3cb5e24..a21d3ee 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -47,7 +47,7 @@ class DebugFlags {
public static final boolean WEB_VIEW_CORE = false;
/*
* Set to true to allow the WebTextView to draw on top of the web page in a
- * different color so that you can see how the two line up.
+ * different color with no background so you can see how the two line up.
*/
public static final boolean DRAW_WEBTEXTVIEW = false;
}
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index d54230c..b8c4e22 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -25,7 +25,7 @@ import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
+import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
@@ -87,7 +87,6 @@ import junit.framework.Assert;
// Keep track of the text before the change so we know whether we actually
// need to send down the DOM events.
private String mPreChange;
- private Drawable mBackground;
// Variables for keeping track of the touch down, to send to the WebView
// when a drag starts
private float mDragStartX;
@@ -190,6 +189,8 @@ import junit.framework.Assert;
// that other applications that use embedded WebViews will properly
// display the text in password textfields.
setTextColor(DebugFlags.DRAW_WEBTEXTVIEW ? Color.RED : Color.BLACK);
+ setBackgroundDrawable(DebugFlags.DRAW_WEBTEXTVIEW ? null : new ColorDrawable(Color.WHITE));
+
// This helps to align the text better with the text in the web page.
setIncludeFontPadding(false);
@@ -423,24 +424,6 @@ import junit.framework.Assert;
// makeNewLayout does.
super.makeNewLayout(w, hintWidth, boring, hintBoring, ellipsisWidth,
bringIntoView);
-
- // For fields that do not draw, create a layout which is altered so that
- // the text lines up.
- if (DebugFlags.DRAW_WEBTEXTVIEW || willNotDraw()) {
- float lineHeight = -1;
- if (mWebView != null) {
- float height = mWebView.nativeFocusCandidateLineHeight();
- if (height != -1) {
- lineHeight = height * mWebView.getScale();
- }
- }
- CharSequence text = getText();
- // Copy from the existing Layout.
- mLayout = new WebTextViewLayout(text, text, getPaint(), mLayout.getWidth(),
- mLayout.getAlignment(), mLayout.getSpacingMultiplier(),
- mLayout.getSpacingAdd(), false, null, ellipsisWidth,
- lineHeight);
- }
lineUpScroll();
}
@@ -491,51 +474,6 @@ import junit.framework.Assert;
return connection;
}
- /**
- * In general, TextView makes a call to InputMethodManager.updateSelection
- * in onDraw. However, in the general case of WebTextView, we do not draw.
- * This method is called by WebView.onDraw to take care of the part that
- * needs to be called.
- */
- /* package */ void onDrawSubstitute() {
- if (!willNotDraw()) {
- // If the WebTextView is set to draw, such as in the case of a
- // password, onDraw calls updateSelection(), so this code path is
- // unnecessary.
- return;
- }
- // This code is copied from TextView.onDraw(). That code does not get
- // executed, however, because the WebTextView does not draw, allowing
- // webkit's drawing to show through.
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null && imm.isActive(this)) {
- Spannable sp = (Spannable) getText();
- int selStart = Selection.getSelectionStart(sp);
- int selEnd = Selection.getSelectionEnd(sp);
- int candStart = EditableInputConnection.getComposingSpanStart(sp);
- int candEnd = EditableInputConnection.getComposingSpanEnd(sp);
- imm.updateSelection(this, selStart, selEnd, candStart, candEnd);
- }
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- // onDraw should only be called for password fields. If WebTextView is
- // still drawing, but is no longer corresponding to a password field,
- // remove it.
- if (!DebugFlags.DRAW_WEBTEXTVIEW && (mWebView == null
- || !mWebView.nativeFocusCandidateIsPassword()
- || !isSameTextField(mWebView.nativeFocusCandidatePointer()))) {
- // Although calling remove() would seem to make more sense here,
- // changing it to not be a password field will make it not draw.
- // Other code will make sure that it is removed completely, but this
- // way the user will not see it.
- setInPassword(false);
- } else {
- super.onDraw(canvas);
- }
- }
-
@Override
public void onEditorAction(int actionCode) {
switch (actionCode) {
@@ -928,102 +866,6 @@ import junit.framework.Assert;
if (mWebView != null) mWebView.incrementTextGeneration();
}
- /**
- * Determine whether to use the system-wide password disguising method,
- * or to use none.
- * @param inPassword True if the textfield is a password field.
- */
- /* package */ void setInPassword(boolean inPassword) {
- if (inPassword) {
- setInputType(InputType.TYPE_CLASS_TEXT | EditorInfo.
- TYPE_TEXT_VARIATION_WEB_PASSWORD);
- createBackground();
- }
- // For password fields, draw the WebTextView. For others, just show
- // webkit's drawing.
- if (!DebugFlags.DRAW_WEBTEXTVIEW) {
- setWillNotDraw(!inPassword);
- }
- setBackgroundDrawable(inPassword ? mBackground : null);
- }
-
- /**
- * Private class used for the background of a password textfield.
- */
- private static class OutlineDrawable extends Drawable {
- private Paint mBackgroundPaint;
- private Paint mOutlinePaint;
- private float[] mLines;
- public OutlineDrawable() {
- mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mBackgroundPaint.setColor(Color.WHITE);
-
- mOutlinePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
- mOutlinePaint.setColor(Color.BLACK);
- mOutlinePaint.setStyle(Paint.Style.STROKE);
-
- mLines = new float[16];
- }
- @Override
- public void setBounds(int left, int top, int right, int bottom) {
- super.setBounds(left, top, right, bottom);
- bottom--;
- right -= 2;
- // Top line
- mLines[0] = left;
- mLines[1] = top + 1;
- mLines[2] = right;
- mLines[3] = top + 1;
- // Right line
- mLines[4] = right;
- mLines[5] = top;
- mLines[6] = right;
- mLines[7] = bottom;
- // Bottom line
- mLines[8] = left;
- mLines[9] = bottom;
- mLines[10] = right;
- mLines[11] = bottom;
- // Left line
- mLines[12] = left + 1;
- mLines[13] = top;
- mLines[14] = left + 1;
- mLines[15] = bottom;
- }
- @Override
- public void draw(Canvas canvas) {
- // Draw the background.
- canvas.drawRect(getBounds(), mBackgroundPaint);
- // Draw the outline.
- canvas.drawLines(mLines, mOutlinePaint);
- }
- // Always want it to be opaque.
- @Override
- public int getOpacity() {
- return PixelFormat.OPAQUE;
- }
- // These are needed because they are abstract in Drawable.
- @Override
- public void setAlpha(int alpha) { }
- @Override
- public void setColorFilter(ColorFilter cf) { }
- }
-
- /**
- * Create a background for the WebTextView and set up the paint for drawing
- * the text. This way, we can see the password transformation of the
- * system, which (optionally) shows the actual text before changing to dots.
- * The background is necessary to hide the webkit-drawn text beneath.
- */
- private void createBackground() {
- if (mBackground != null) {
- return;
- }
- mBackground = new OutlineDrawable();
-
- setGravity(Gravity.CENTER_VERTICAL);
- }
-
@Override
public void setInputType(int type) {
mFromSetInputType = true;
@@ -1072,7 +914,8 @@ import junit.framework.Assert;
lp.height = height;
}
if (getParent() == null) {
- mWebView.addView(this, lp);
+ // Insert the view so that it's drawn first (at index 0)
+ mWebView.addView(this, 0, lp);
} else {
setLayoutParams(lp);
}
@@ -1145,7 +988,6 @@ import junit.framework.Assert;
/* package */ void setType(int type) {
if (mWebView == null) return;
boolean single = true;
- boolean inPassword = false;
int maxLength = -1;
int inputType = InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
@@ -1167,7 +1009,7 @@ import junit.framework.Assert;
imeOptions |= EditorInfo.IME_ACTION_NONE;
break;
case PASSWORD:
- inPassword = true;
+ inputType |= EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD;
imeOptions |= EditorInfo.IME_ACTION_GO;
break;
case SEARCH:
@@ -1219,7 +1061,7 @@ import junit.framework.Assert;
setHorizontallyScrolling(single);
setInputType(inputType);
setImeOptions(imeOptions);
- setInPassword(inPassword);
+ setVisibility(VISIBLE);
AutoCompleteAdapter adapter = null;
setAdapterCustom(adapter);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index e24ab58..a935a67 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4068,9 +4068,6 @@ public class WebView extends AbsoluteLayout
if (AUTO_REDRAW_HACK && mAutoRedraw) {
invalidate();
}
- if (inEditingMode()) {
- mWebTextView.onDrawSubstitute();
- }
mWebViewCore.signalRepaintDone();
if (mOverScrollGlow != null && mOverScrollGlow.drawEdgeGlows(canvas)) {
@@ -4287,18 +4284,18 @@ public class WebView extends AbsoluteLayout
private void onZoomAnimationStart() {
// If it is in password mode, turn it off so it does not draw misplaced.
- if (inEditingMode() && nativeFocusCandidateIsPassword()) {
- mWebTextView.setInPassword(false);
+ if (inEditingMode()) {
+ mWebTextView.setVisibility(INVISIBLE);
}
}
private void onZoomAnimationEnd() {
// adjust the edit text view if needed
- if (inEditingMode() && didUpdateWebTextViewDimensions(FULLY_ON_SCREEN)
- && nativeFocusCandidateIsPassword()) {
+ if (inEditingMode()
+ && didUpdateWebTextViewDimensions(FULLY_ON_SCREEN)) {
// If it is a password field, start drawing the WebTextView once
// again.
- mWebTextView.setInPassword(true);
+ mWebTextView.setVisibility(VISIBLE);
}
}
@@ -4593,37 +4590,23 @@ public class WebView extends AbsoluteLayout
}
String text = nativeFocusCandidateText();
int nodePointer = nativeFocusCandidatePointer();
- if (alreadyThere && mWebTextView.isSameTextField(nodePointer)) {
- // It is possible that we have the same textfield, but it has moved,
- // i.e. In the case of opening/closing the screen.
- // In that case, we need to set the dimensions, but not the other
- // aspects.
- // If the text has been changed by webkit, update it. However, if
- // there has been more UI text input, ignore it. We will receive
- // another update when that text is recognized.
- if (text != null && !text.equals(mWebTextView.getText().toString())
- && nativeTextGeneration() == mTextGeneration) {
- mWebTextView.setTextAndKeepSelection(text);
- }
- } else {
- mWebTextView.setGravity(nativeFocusCandidateIsRtlText() ?
- Gravity.RIGHT : Gravity.NO_GRAVITY);
- // This needs to be called before setType, which may call
- // requestFormData, and it needs to have the correct nodePointer.
- mWebTextView.setNodePointer(nodePointer);
- mWebTextView.setType(nativeFocusCandidateType());
- updateWebTextViewPadding();
- if (null == text) {
- if (DebugFlags.WEB_VIEW) {
- Log.v(LOGTAG, "rebuildWebTextView null == text");
- }
- text = "";
- }
- mWebTextView.setTextAndKeepSelection(text);
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null && imm.isActive(mWebTextView)) {
- imm.restartInput(mWebTextView);
+ mWebTextView.setGravity(nativeFocusCandidateIsRtlText() ?
+ Gravity.RIGHT : Gravity.NO_GRAVITY);
+ // This needs to be called before setType, which may call
+ // requestFormData, and it needs to have the correct nodePointer.
+ mWebTextView.setNodePointer(nodePointer);
+ mWebTextView.setType(nativeFocusCandidateType());
+ updateWebTextViewPadding();
+ if (null == text) {
+ if (DebugFlags.WEB_VIEW) {
+ Log.v(LOGTAG, "rebuildWebTextView null == text");
}
+ text = "";
+ }
+ mWebTextView.setTextAndKeepSelection(text);
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null && imm.isActive(mWebTextView)) {
+ imm.restartInput(mWebTextView);
}
if (isFocused()) {
mWebTextView.requestFocus();
@@ -8120,19 +8103,7 @@ public class WebView extends AbsoluteLayout
// and representing the same node as the pointer.
if (inEditingMode() &&
mWebTextView.isSameTextField(msg.arg1)) {
- if (msg.getData().getBoolean("password")) {
- Spannable text = (Spannable) mWebTextView.getText();
- int start = Selection.getSelectionStart(text);
- int end = Selection.getSelectionEnd(text);
- mWebTextView.setInPassword(true);
- // Restore the selection, which may have been
- // ruined by setInPassword.
- Spannable pword =
- (Spannable) mWebTextView.getText();
- Selection.setSelection(pword, start, end);
- // If the text entry has created more events, ignore
- // this one.
- } else if (msg.arg2 == mTextGeneration) {
+ if (msg.arg2 == mTextGeneration) {
String text = (String) msg.obj;
if (null == text) {
text = "";
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 5eba1a0..0b0b812 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -34,12 +34,17 @@ import android.widget.RemoteViews.RemoteView;
/**
* FrameLayout is designed to block out an area on the screen to display
- * a single item. You can add multiple children to a FrameLayout and control their
- * position within the FrameLayout using {@link android.widget.FrameLayout.LayoutParams#gravity}.
- * Children are drawn in a stack, with the most recently added child on top.
- * The size of the frame layout is the size of its largest child (plus padding), visible
- * or not (if the FrameLayout's parent permits). Views that are GONE are used for sizing
- * only if {@link #setMeasureAllChildren(boolean) setMeasureAllChildren()}
+ * a single item. Generally, FrameLayout should be used to hold a single child view, because it can
+ * be difficult to organize child views in a way that's scalable to different screen sizes without
+ * the children overlapping each other. You can, however, add multiple children to a FrameLayout
+ * and control their position within the FrameLayout by assigning gravity to each child, using the
+ * <a href="FrameLayout.LayoutParams.html#attr_android:layout_gravity">{@code
+ * android:layout_gravity}</a> attribute.
+ * <p>Child views are drawn in a stack, with the most recently added child on top.
+ * The size of the FrameLayout is the size of its largest child (plus padding), visible
+ * or not (if the FrameLayout's parent permits). Views that are {@link android.view.View#GONE} are
+ * used for sizing
+ * only if {@link #setMeasureAllChildren(boolean) setConsiderGoneChildrenWhenMeasuring()}
* is set to true.
*
* @attr ref android.R.styleable#FrameLayout_foreground
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 55b73df..91b19ed 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -221,6 +221,7 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
mCloseButton.setOnClickListener(mOnClickListener);
mSubmitButton.setOnClickListener(mOnClickListener);
mVoiceButton.setOnClickListener(mOnClickListener);
+ mQueryTextView.setOnClickListener(mOnClickListener);
mQueryTextView.addTextChangedListener(mTextWatcher);
mQueryTextView.setOnEditorActionListener(mOnEditorActionListener);
@@ -319,7 +320,9 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
// If it is not iconified, then give the focus to the text field
if (!isIconified()) {
boolean result = mQueryTextView.requestFocus(direction, previouslyFocusedRect);
- if (result) updateViewsVisibility(false);
+ if (result) {
+ updateViewsVisibility(false);
+ }
return result;
} else {
return super.requestFocus(direction, previouslyFocusedRect);
@@ -330,9 +333,9 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
@Override
public void clearFocus() {
mClearingFocus = true;
+ setImeVisibility(false);
super.clearFocus();
mQueryTextView.clearFocus();
- setImeVisibility(false);
mClearingFocus = false;
}
@@ -681,6 +684,8 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
onSubmitQuery();
} else if (v == mVoiceButton) {
onVoiceClicked();
+ } else if (v == mQueryTextView) {
+ forceSuggestionQuery();
}
}
};
@@ -1029,6 +1034,9 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
void onTextFocusChanged() {
updateViewsVisibility(isIconified());
updateFocusedState(mQueryTextView.hasFocus());
+ if (mQueryTextView.hasFocus()) {
+ forceSuggestionQuery();
+ }
}
@Override
@@ -1041,8 +1049,9 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
*/
@Override
public void onActionViewCollapsed() {
+ clearFocus();
+ updateViewsVisibility(true);
mQueryTextView.setText("");
- setIconified(true);
mExpandedInActionView = false;
}
@@ -1376,6 +1385,11 @@ public class SearchView extends LinearLayout implements CollapsibleActionView {
}
}
+ private void forceSuggestionQuery() {
+ mQueryTextView.doBeforeTextChanged();
+ mQueryTextView.doAfterTextChanged();
+ }
+
static boolean isLandscapeMode(Context context) {
return context.getResources().getConfiguration().orientation
== Configuration.ORIENTATION_LANDSCAPE;
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index 9ae7def..1531946 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -1,22 +1,9 @@
package com.android.internal.content;
-import android.content.pm.PackageManager;
import android.os.Build;
-import android.os.FileUtils;
-import android.os.SystemProperties;
-import android.util.Log;
-import android.util.Pair;
import android.util.Slog;
import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Enumeration;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipException;
-import java.util.zip.ZipFile;
/**
* Native libraries helper.
@@ -28,270 +15,22 @@ public class NativeLibraryHelper {
private static final boolean DEBUG_NATIVE = false;
- /*
- * The following constants are returned by listPackageSharedLibsForAbiLI
- * to indicate if native shared libraries were found in the package.
- * Values are:
- * PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES => native libraries found and installed
- * PACKAGE_INSTALL_NATIVE_NO_LIBRARIES => no native libraries in package
- * PACKAGE_INSTALL_NATIVE_ABI_MISMATCH => native libraries for another ABI found
- * in package (and not installed)
- *
- */
- private static final int PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES = 0;
- private static final int PACKAGE_INSTALL_NATIVE_NO_LIBRARIES = 1;
- private static final int PACKAGE_INSTALL_NATIVE_ABI_MISMATCH = 2;
+ private static native long nativeSumNativeBinaries(String file, String cpuAbi, String cpuAbi2);
- // Directory in the APK that holds all the native shared libraries.
- private static final String APK_LIB = "lib/";
- private static final int APK_LIB_LENGTH = APK_LIB.length();
-
- // Prefix that native shared libraries must have.
- private static final String LIB_PREFIX = "lib";
- private static final int LIB_PREFIX_LENGTH = LIB_PREFIX.length();
-
- // Suffix that the native shared libraries must have.
- private static final String LIB_SUFFIX = ".so";
- private static final int LIB_SUFFIX_LENGTH = LIB_SUFFIX.length();
-
- // Name of the GDB binary.
- private static final String GDBSERVER = "gdbserver";
-
- // the minimum length of a valid native shared library of the form
- // lib/<something>/lib<name>.so.
- private static final int MIN_ENTRY_LENGTH = APK_LIB_LENGTH + 2 + LIB_PREFIX_LENGTH + 1
- + LIB_SUFFIX_LENGTH;
-
- /*
- * Find all files of the form lib/<cpuAbi>/lib<name>.so in the .apk
- * and add them to a list to be installed later.
- *
- * NOTE: this method may throw an IOException if the library cannot
- * be copied to its final destination, e.g. if there isn't enough
- * room left on the data partition, or a ZipException if the package
- * file is malformed.
- */
- private static int listPackageSharedLibsForAbiLI(ZipFile zipFile,
- String cpuAbi, List<Pair<ZipEntry, String>> libEntries) throws IOException,
- ZipException {
- final int cpuAbiLen = cpuAbi.length();
- boolean hasNativeLibraries = false;
- boolean installedNativeLibraries = false;
-
- if (DEBUG_NATIVE) {
- Slog.d(TAG, "Checking " + zipFile.getName() + " for shared libraries of CPU ABI type "
- + cpuAbi);
- }
-
- Enumeration<? extends ZipEntry> entries = zipFile.entries();
-
- while (entries.hasMoreElements()) {
- ZipEntry entry = entries.nextElement();
-
- // skip directories
- if (entry.isDirectory()) {
- continue;
- }
- String entryName = entry.getName();
-
- /*
- * Check that the entry looks like lib/<something>/lib<name>.so
- * here, but don't check the ABI just yet.
- *
- * - must be sufficiently long
- * - must end with LIB_SUFFIX, i.e. ".so"
- * - must start with APK_LIB, i.e. "lib/"
- */
- if (entryName.length() < MIN_ENTRY_LENGTH || !entryName.endsWith(LIB_SUFFIX)
- || !entryName.startsWith(APK_LIB)) {
- continue;
- }
-
- // file name must start with LIB_PREFIX, i.e. "lib"
- int lastSlash = entryName.lastIndexOf('/');
-
- if (lastSlash < 0
- || !entryName.regionMatches(lastSlash + 1, LIB_PREFIX, 0, LIB_PREFIX_LENGTH)) {
- continue;
- }
-
- hasNativeLibraries = true;
-
- // check the cpuAbi now, between lib/ and /lib<name>.so
- if (lastSlash != APK_LIB_LENGTH + cpuAbiLen
- || !entryName.regionMatches(APK_LIB_LENGTH, cpuAbi, 0, cpuAbiLen))
- continue;
-
- /*
- * Extract the library file name, ensure it doesn't contain
- * weird characters. we're guaranteed here that it doesn't contain
- * a directory separator though.
- */
- String libFileName = entryName.substring(lastSlash+1);
- if (!FileUtils.isFilenameSafe(new File(libFileName))) {
- continue;
- }
-
- installedNativeLibraries = true;
-
- if (DEBUG_NATIVE) {
- Log.d(TAG, "Caching shared lib " + entry.getName());
- }
-
- libEntries.add(Pair.create(entry, libFileName));
- }
- if (!hasNativeLibraries)
- return PACKAGE_INSTALL_NATIVE_NO_LIBRARIES;
-
- if (!installedNativeLibraries)
- return PACKAGE_INSTALL_NATIVE_ABI_MISMATCH;
-
- return PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES;
+ public static long sumNativeBinariesLI(File apkFile) {
+ final String cpuAbi = Build.CPU_ABI;
+ final String cpuAbi2 = Build.CPU_ABI2;
+ return nativeSumNativeBinaries(apkFile.getPath(), cpuAbi, cpuAbi2);
}
- /*
- * Find the gdbserver executable program in a package at
- * lib/<cpuAbi>/gdbserver and add it to the list of binaries
- * to be copied out later.
- *
- * Returns PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES on success,
- * or PACKAGE_INSTALL_NATIVE_NO_LIBRARIES otherwise.
- */
- private static int listPackageGdbServerLI(ZipFile zipFile, String cpuAbi,
- List<Pair<ZipEntry, String>> nativeFiles) throws IOException, ZipException {
- final String apkGdbServerPath = "lib/" + cpuAbi + "/" + GDBSERVER;
-
- Enumeration<? extends ZipEntry> entries = zipFile.entries();
-
- while (entries.hasMoreElements()) {
- ZipEntry entry = entries.nextElement();
- // skip directories
- if (entry.isDirectory()) {
- continue;
- }
- String entryName = entry.getName();
-
- if (!entryName.equals(apkGdbServerPath)) {
- continue;
- }
-
- if (false) {
- Log.d(TAG, "Found gdbserver: " + entry.getName());
- }
+ private native static int nativeCopyNativeBinaries(String filePath, String sharedLibraryPath,
+ String cpuAbi, String cpuAbi2);
- final String installGdbServerPath = GDBSERVER;
- nativeFiles.add(Pair.create(entry, installGdbServerPath));
-
- return PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES;
- }
- return PACKAGE_INSTALL_NATIVE_NO_LIBRARIES;
- }
-
- /*
- * Examine shared libraries stored in the APK as
- * lib/<cpuAbi>/lib<name>.so and add them to a list to be copied
- * later.
- *
- * This function will first try the main CPU ABI defined by Build.CPU_ABI
- * (which corresponds to ro.product.cpu.abi), and also try an alternate
- * one if ro.product.cpu.abi2 is defined.
- */
- public static int listPackageNativeBinariesLI(ZipFile zipFile,
- List<Pair<ZipEntry, String>> nativeFiles) throws ZipException, IOException {
- String cpuAbi = Build.CPU_ABI;
-
- int result = listPackageSharedLibsForAbiLI(zipFile, cpuAbi, nativeFiles);
-
- /*
- * Some architectures are capable of supporting several CPU ABIs
- * for example, 'armeabi-v7a' also supports 'armeabi' native code
- * this is indicated by the definition of the ro.product.cpu.abi2
- * system property.
- *
- * only scan the package twice in case of ABI mismatch
- */
- if (result == PACKAGE_INSTALL_NATIVE_ABI_MISMATCH) {
- final String cpuAbi2 = SystemProperties.get("ro.product.cpu.abi2", null);
- if (cpuAbi2 != null) {
- result = listPackageSharedLibsForAbiLI(zipFile, cpuAbi2, nativeFiles);
- }
-
- if (result == PACKAGE_INSTALL_NATIVE_ABI_MISMATCH) {
- Slog.w(TAG, "Native ABI mismatch from package file");
- return PackageManager.INSTALL_FAILED_INVALID_APK;
- }
-
- if (result == PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES) {
- cpuAbi = cpuAbi2;
- }
- }
-
- /*
- * Debuggable packages may have gdbserver embedded, so add it to
- * the list to the list of items to be extracted (as lib/gdbserver)
- * into the application's native library directory later.
- */
- if (result == PACKAGE_INSTALL_NATIVE_FOUND_LIBRARIES) {
- listPackageGdbServerLI(zipFile, cpuAbi, nativeFiles);
- }
- return PackageManager.INSTALL_SUCCEEDED;
- }
-
- public static int copyNativeBinariesLI(File scanFile, File sharedLibraryDir) {
- /*
- * Check all the native files that need to be copied and add
- * that to the container size.
- */
- ZipFile zipFile;
- try {
- zipFile = new ZipFile(scanFile);
-
- List<Pair<ZipEntry, String>> nativeFiles = new LinkedList<Pair<ZipEntry, String>>();
-
- NativeLibraryHelper.listPackageNativeBinariesLI(zipFile, nativeFiles);
-
- final int N = nativeFiles.size();
-
- for (int i = 0; i < N; i++) {
- final Pair<ZipEntry, String> entry = nativeFiles.get(i);
-
- File destFile = new File(sharedLibraryDir, entry.second);
- copyNativeBinaryLI(zipFile, entry.first, sharedLibraryDir, destFile);
- }
- zipFile.close();
- } catch (ZipException e) {
- Slog.w(TAG, "Failed to extract data from package file", e);
- return PackageManager.INSTALL_FAILED_INVALID_APK;
- } catch (IOException e) {
- Slog.w(TAG, "Failed to cache package shared libs", e);
- return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
- }
-
- return PackageManager.INSTALL_SUCCEEDED;
- }
-
- private static void copyNativeBinaryLI(ZipFile zipFile, ZipEntry entry,
- File binaryDir, File binaryFile) throws IOException {
- InputStream inputStream = zipFile.getInputStream(entry);
- try {
- File tempFile = File.createTempFile("tmp", "tmp", binaryDir);
- String tempFilePath = tempFile.getPath();
- // XXX package manager can't change owner, so the executable files for
- // now need to be left as world readable and owned by the system.
- if (!FileUtils.copyToFile(inputStream, tempFile)
- || !tempFile.setLastModified(entry.getTime())
- || FileUtils.setPermissions(tempFilePath, FileUtils.S_IRUSR | FileUtils.S_IWUSR
- | FileUtils.S_IRGRP | FileUtils.S_IXUSR | FileUtils.S_IXGRP
- | FileUtils.S_IXOTH | FileUtils.S_IROTH, -1, -1) != 0
- || !tempFile.renameTo(binaryFile)) {
- // Failed to properly write file.
- tempFile.delete();
- throw new IOException("Couldn't create cached binary " + binaryFile + " in "
- + binaryDir);
- }
- } finally {
- inputStream.close();
- }
+ public static int copyNativeBinariesIfNeededLI(File apkFile, File sharedLibraryDir) {
+ final String cpuAbi = Build.CPU_ABI;
+ final String cpuAbi2 = Build.CPU_ABI2;
+ return nativeCopyNativeBinaries(apkFile.getPath(), sharedLibraryDir.getPath(), cpuAbi,
+ cpuAbi2);
}
// Convenience method to call removeNativeBinariesFromDirLI(File)
diff --git a/core/java/com/android/internal/view/menu/ActionMenuView.java b/core/java/com/android/internal/view/menu/ActionMenuView.java
index bf2965b..bff621c 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuView.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuView.java
@@ -36,8 +36,8 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
private boolean mReserveOverflow;
private ActionMenuPresenter mPresenter;
- private boolean mUpdateContentsBeforeMeasure;
private boolean mFormatItems;
+ private int mFormatItemsWidth;
private int mMinCellSize;
private int mMeasuredExtraWidth;
@@ -71,19 +71,21 @@ public class ActionMenuView extends LinearLayout implements MenuBuilder.ItemInvo
}
@Override
- public void requestLayout() {
- // Layout can influence how many action items fit.
- mUpdateContentsBeforeMeasure = true;
- super.requestLayout();
- }
-
- @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// If we've been given an exact size to match, apply special formatting during layout.
+ final boolean wasFormatted = mFormatItems;
mFormatItems = MeasureSpec.getMode(widthMeasureSpec) == MeasureSpec.EXACTLY;
- if (mUpdateContentsBeforeMeasure && mMenu != null) {
+
+ if (wasFormatted != mFormatItems) {
+ mFormatItemsWidth = 0; // Reset this when switching modes
+ }
+
+ // Special formatting can change whether items can fit as action buttons.
+ // Kick the menu and update presenters when this changes.
+ final int widthSize = MeasureSpec.getMode(widthMeasureSpec);
+ if (mFormatItems && mMenu != null && widthSize != mFormatItemsWidth) {
+ mFormatItemsWidth = widthSize;
mMenu.onItemsChanged(true);
- mUpdateContentsBeforeMeasure = false;
}
if (mFormatItems) {
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index 159b3da..19cbe25 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -27,6 +27,7 @@ import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Parcelable;
+import android.util.Log;
import android.util.SparseArray;
import android.view.ActionProvider;
import android.view.ContextMenu.ContextMenuInfo;
@@ -47,7 +48,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
* standard menu UI.
*/
public class MenuBuilder implements Menu {
- private static final String LOGTAG = "MenuBuilder";
+ private static final String TAG = "MenuBuilder";
private static final String PRESENTER_KEY = "android:menu:presenters";
private static final String ACTION_VIEW_STATES_KEY = "android:menu:actionviewstates";
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index b0a002d..8b53bb8 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -563,7 +563,7 @@ public final class MenuItemImpl implements MenuItem {
public MenuItem setActionView(int resId) {
final Context context = mMenu.getContext();
final LayoutInflater inflater = LayoutInflater.from(context);
- setActionView(inflater.inflate(resId, new LinearLayout(context)));
+ setActionView(inflater.inflate(resId, new LinearLayout(context), false));
return this;
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 09262e0..468f28e 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -1323,11 +1323,18 @@ public class ActionBarView extends AbsActionBarView {
if (mExpandedActionView instanceof CollapsibleActionView) {
((CollapsibleActionView) mExpandedActionView).onActionViewExpanded();
}
+
return true;
}
@Override
public boolean collapseItemActionView(MenuBuilder menu, MenuItemImpl item) {
+ // Do this before detaching the actionview from the hierarchy, in case
+ // it needs to dismiss the soft keyboard, etc.
+ if (mExpandedActionView instanceof CollapsibleActionView) {
+ ((CollapsibleActionView) mExpandedActionView).onActionViewCollapsed();
+ }
+
removeView(mExpandedActionView);
removeView(mExpandedHomeLayout);
if ((mDisplayOptions & ActionBar.DISPLAY_SHOW_HOME) != 0) {
@@ -1349,16 +1356,12 @@ public class ActionBarView extends AbsActionBarView {
if (mCustomNavView != null && (mDisplayOptions & ActionBar.DISPLAY_SHOW_CUSTOM) != 0) {
mCustomNavView.setVisibility(VISIBLE);
}
- View collapsedView = mExpandedActionView;
mExpandedActionView = null;
mExpandedHomeLayout.setIcon(null);
mCurrentExpandedItem = null;
requestLayout();
item.setActionViewExpanded(false);
- if (collapsedView instanceof CollapsibleActionView) {
- ((CollapsibleActionView) collapsedView).onActionViewCollapsed();
- }
return true;
}