Merge "InputFilter not updated on global accessibility change."
diff --git a/api/current.txt b/api/current.txt
index 91cf3fa..77e31b9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2331,7 +2331,7 @@
method public abstract void onTabUnselected(android.app.ActionBar.Tab, android.app.FragmentTransaction);
}
- public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
+ public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
ctor public Activity();
method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
method public void closeContextMenu();
@@ -2436,6 +2436,7 @@
method protected void onTitleChanged(java.lang.CharSequence, int);
method public boolean onTouchEvent(android.view.MotionEvent);
method public boolean onTrackballEvent(android.view.MotionEvent);
+ method public void onTrimMemory(int);
method public void onUserInteraction();
method protected void onUserLeaveHint();
method public void onWindowAttributesChanged(android.view.WindowManager.LayoutParams);
@@ -2731,12 +2732,25 @@
ctor public AliasActivity();
}
- public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks {
+ public class Application extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
ctor public Application();
method public void onConfigurationChanged(android.content.res.Configuration);
method public void onCreate();
method public void onLowMemory();
method public void onTerminate();
+ method public void onTrimMemory(int);
+ method public void registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks);
+ method public void unregisterActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks);
+ }
+
+ public static abstract interface Application.ActivityLifecycleCallbacks {
+ method public abstract void onActivityCreated(android.app.Activity, android.os.Bundle);
+ method public abstract void onActivityDestroyed(android.app.Activity);
+ method public abstract void onActivityPaused(android.app.Activity);
+ method public abstract void onActivityResumed(android.app.Activity);
+ method public abstract void onActivitySaveInstanceState(android.app.Activity, android.os.Bundle);
+ method public abstract void onActivityStarted(android.app.Activity);
+ method public abstract void onActivityStopped(android.app.Activity);
}
public class DatePickerDialog extends android.app.AlertDialog implements android.widget.DatePicker.OnDateChangedListener android.content.DialogInterface.OnClickListener {
@@ -2955,7 +2969,7 @@
method public void setSelectedGroup(int);
}
- public class Fragment implements android.content.ComponentCallbacks android.view.View.OnCreateContextMenuListener {
+ public class Fragment implements android.content.ComponentCallbacks2 android.view.View.OnCreateContextMenuListener {
ctor public Fragment();
method public void dump(java.lang.String, java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
method public final boolean equals(java.lang.Object);
@@ -3009,6 +3023,7 @@
method public void onSaveInstanceState(android.os.Bundle);
method public void onStart();
method public void onStop();
+ method public void onTrimMemory(int);
method public void onViewCreated(android.view.View, android.os.Bundle);
method public void registerForContextMenu(android.view.View);
method public void setArguments(android.os.Bundle);
@@ -3545,7 +3560,7 @@
field public static final android.os.Parcelable.Creator CREATOR;
}
- public abstract class Service extends android.content.ContextWrapper implements android.content.ComponentCallbacks {
+ public abstract class Service extends android.content.ContextWrapper implements android.content.ComponentCallbacks2 {
ctor public Service();
method protected void dump(java.io.FileDescriptor, java.io.PrintWriter, java.lang.String[]);
method public final android.app.Application getApplication();
@@ -3558,6 +3573,7 @@
method public deprecated void onStart(android.content.Intent, int);
method public int onStartCommand(android.content.Intent, int, int);
method public void onTaskRemoved(android.content.Intent);
+ method public void onTrimMemory(int);
method public boolean onUnbind(android.content.Intent);
method public final void startForeground(int, android.app.Notification);
method public final void stopForeground(boolean);
@@ -4442,6 +4458,14 @@
method public abstract void onLowMemory();
}
+ public abstract interface ComponentCallbacks2 implements android.content.ComponentCallbacks {
+ method public abstract void onTrimMemory(int);
+ field public static final int TRIM_MEMORY_BACKGROUND = 40; // 0x28
+ field public static final int TRIM_MEMORY_COMPLETE = 80; // 0x50
+ field public static final int TRIM_MEMORY_MODERATE = 60; // 0x3c
+ field public static final int TRIM_MEMORY_UI_HIDDEN = 20; // 0x14
+ }
+
public final class ComponentName implements java.lang.Cloneable java.lang.Comparable android.os.Parcelable {
ctor public ComponentName(java.lang.String, java.lang.String);
ctor public ComponentName(android.content.Context, java.lang.String);
@@ -4463,7 +4487,7 @@
field public static final android.os.Parcelable.Creator CREATOR;
}
- public abstract class ContentProvider implements android.content.ComponentCallbacks {
+ public abstract class ContentProvider implements android.content.ComponentCallbacks2 {
ctor public ContentProvider();
method public android.content.ContentProviderResult[] applyBatch(java.util.ArrayList<android.content.ContentProviderOperation>) throws android.content.OperationApplicationException;
method public void attachInfo(android.content.Context, android.content.pm.ProviderInfo);
@@ -4481,6 +4505,7 @@
method public void onConfigurationChanged(android.content.res.Configuration);
method public abstract boolean onCreate();
method public void onLowMemory();
+ method public void onTrimMemory(int);
method public android.content.res.AssetFileDescriptor openAssetFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
method public android.os.ParcelFileDescriptor openFile(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
method protected final android.os.ParcelFileDescriptor openFileHelper(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException;
@@ -4734,6 +4759,7 @@
method public abstract android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory);
method public abstract android.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.String, int, android.database.sqlite.SQLiteDatabase.CursorFactory, android.database.DatabaseErrorHandler);
method public abstract deprecated android.graphics.drawable.Drawable peekWallpaper();
+ method public void registerComponentCallbacks(android.content.ComponentCallbacks);
method public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter);
method public abstract android.content.Intent registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter, java.lang.String, android.os.Handler);
method public abstract void removeStickyBroadcast(android.content.Intent);
@@ -4754,15 +4780,21 @@
method public abstract android.content.ComponentName startService(android.content.Intent);
method public abstract boolean stopService(android.content.Intent);
method public abstract void unbindService(android.content.ServiceConnection);
+ method public void unregisterComponentCallbacks(android.content.ComponentCallbacks);
method public abstract void unregisterReceiver(android.content.BroadcastReceiver);
field public static final java.lang.String ACCESSIBILITY_SERVICE = "accessibility";
field public static final java.lang.String ACCOUNT_SERVICE = "account";
field public static final java.lang.String ACTIVITY_SERVICE = "activity";
field public static final java.lang.String ALARM_SERVICE = "alarm";
field public static final java.lang.String AUDIO_SERVICE = "audio";
+ field public static final int BIND_ABOVE_CLIENT = 8; // 0x8
+ field public static final int BIND_ADJUST_WITH_ACTIVITY = 64; // 0x40
+ field public static final int BIND_ALLOW_OOM_MANAGEMENT = 16; // 0x10
field public static final int BIND_AUTO_CREATE = 1; // 0x1
field public static final int BIND_DEBUG_UNBIND = 2; // 0x2
+ field public static final int BIND_IMPORTANT = 64; // 0x40
field public static final int BIND_NOT_FOREGROUND = 4; // 0x4
+ field public static final int BIND_WAIVE_PRIORITY = 32; // 0x20
field public static final java.lang.String CLIPBOARD_SERVICE = "clipboard";
field public static final java.lang.String CONNECTIVITY_SERVICE = "connectivity";
field public static final int CONTEXT_IGNORE_SECURITY = 2; // 0x2
@@ -22666,8 +22698,11 @@
field protected static final int[] SELECTED_STATE_SET;
field protected static final int[] SELECTED_WINDOW_FOCUSED_STATE_SET;
field public static final int SOUND_EFFECTS_ENABLED = 134217728; // 0x8000000
- field public static final int STATUS_BAR_HIDDEN = 1; // 0x1
- field public static final int STATUS_BAR_VISIBLE = 0; // 0x0
+ field public static final deprecated int STATUS_BAR_HIDDEN = 1; // 0x1
+ field public static final deprecated int STATUS_BAR_VISIBLE = 0; // 0x0
+ field public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 2; // 0x2
+ field public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 1; // 0x1
+ field public static final int SYSTEM_UI_FLAG_VISIBLE = 0; // 0x0
field public static android.util.Property TRANSLATION_X;
field public static android.util.Property TRANSLATION_Y;
field protected static final java.lang.String VIEW_LOG_TAG = "View";
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index fb1570e..d5b669e 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -19,7 +19,7 @@
import com.android.internal.app.ActionBarImpl;
import com.android.internal.policy.PolicyManager;
-import android.content.ComponentCallbacks;
+import android.content.ComponentCallbacks2;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -626,7 +626,7 @@
public class Activity extends ContextThemeWrapper
implements LayoutInflater.Factory2,
Window.Callback, KeyEvent.Callback,
- OnCreateContextMenuListener, ComponentCallbacks {
+ OnCreateContextMenuListener, ComponentCallbacks2 {
private static final String TAG = "Activity";
/** Standard activity result: operation canceled. */
@@ -859,6 +859,7 @@
? mLastNonConfigurationInstances.fragments : null);
}
mFragments.dispatchCreate();
+ getApplication().dispatchActivityCreated(this, savedInstanceState);
mCalled = true;
}
@@ -1001,6 +1002,8 @@
}
mCheckedForLoaderManager = true;
}
+
+ getApplication().dispatchActivityStarted(this);
}
/**
@@ -1048,6 +1051,7 @@
* @see #onPause
*/
protected void onResume() {
+ getApplication().dispatchActivityResumed(this);
mCalled = true;
}
@@ -1158,6 +1162,7 @@
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
+ getApplication().dispatchActivitySaveInstanceState(this, outState);
}
/**
@@ -1234,6 +1239,7 @@
* @see #onStop
*/
protected void onPause() {
+ getApplication().dispatchActivityPaused(this);
mCalled = true;
}
@@ -1320,6 +1326,7 @@
*/
protected void onStop() {
if (mActionBar != null) mActionBar.setShowHideAnimationEnabled(false);
+ getApplication().dispatchActivityStopped(this);
mCalled = true;
}
@@ -1382,6 +1389,8 @@
if (mSearchManager != null) {
mSearchManager.stopSearch();
}
+
+ getApplication().dispatchActivityDestroyed(this);
}
/**
@@ -1580,12 +1589,17 @@
nci.loaders = mAllLoaderManagers;
return nci;
}
-
+
public void onLowMemory() {
mCalled = true;
mFragments.dispatchLowMemory();
}
-
+
+ public void onTrimMemory(int level) {
+ mCalled = true;
+ mFragments.dispatchTrimMemory(level);
+ }
+
/**
* Return the FragmentManager for interacting with fragments associated
* with this activity.
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 1e93f88..8931675 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -18,7 +18,7 @@
import android.app.backup.BackupAgent;
import android.content.BroadcastReceiver;
-import android.content.ComponentCallbacks;
+import android.content.ComponentCallbacks2;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.Context;
@@ -3258,10 +3258,10 @@
}
}
- ArrayList<ComponentCallbacks> collectComponentCallbacksLocked(
+ ArrayList<ComponentCallbacks2> collectComponentCallbacksLocked(
boolean allActivities, Configuration newConfig) {
- ArrayList<ComponentCallbacks> callbacks
- = new ArrayList<ComponentCallbacks>();
+ ArrayList<ComponentCallbacks2> callbacks
+ = new ArrayList<ComponentCallbacks2>();
if (mActivities.size() > 0) {
Iterator<ActivityClientRecord> it = mActivities.values().iterator();
@@ -3311,10 +3311,10 @@
return callbacks;
}
- private void performConfigurationChanged(
- ComponentCallbacks cb, Configuration config) {
+ private final void performConfigurationChanged(
+ ComponentCallbacks2 cb, Configuration config) {
// Only for Activity objects, check that they actually call up to their
- // superclass implementation. ComponentCallbacks is an interface, so
+ // superclass implementation. ComponentCallbacks2 is an interface, so
// we check the runtime type and act accordingly.
Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
if (activity != null) {
@@ -3418,7 +3418,7 @@
final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
- ArrayList<ComponentCallbacks> callbacks = null;
+ ArrayList<ComponentCallbacks2> callbacks = null;
synchronized (mPackages) {
if (mPendingConfiguration != null) {
@@ -3558,7 +3558,7 @@
}
final void handleLowMemory() {
- ArrayList<ComponentCallbacks> callbacks;
+ ArrayList<ComponentCallbacks2> callbacks;
synchronized (mPackages) {
callbacks = collectComponentCallbacksLocked(true, null);
@@ -3583,6 +3583,16 @@
final void handleTrimMemory(int level) {
WindowManagerImpl.getDefault().trimMemory(level);
+ ArrayList<ComponentCallbacks2> callbacks;
+
+ synchronized (mPackages) {
+ callbacks = collectComponentCallbacksLocked(true, null);
+ }
+
+ final int N = callbacks.size();
+ for (int i=0; i<N; i++) {
+ callbacks.get(i).onTrimMemory(level);
+ }
}
private void handleBindApplication(AppBindData data) {
@@ -4128,7 +4138,7 @@
}
}
- ViewRootImpl.addConfigCallback(new ComponentCallbacks() {
+ ViewRootImpl.addConfigCallback(new ComponentCallbacks2() {
public void onConfigurationChanged(Configuration newConfig) {
synchronized (mPackages) {
// We need to apply this change to the resources
@@ -4148,6 +4158,8 @@
}
public void onLowMemory() {
}
+ public void onTrimMemory(int level) {
+ }
});
}
diff --git a/core/java/android/app/Application.java b/core/java/android/app/Application.java
index 10cc9f8..dd9ea26 100644
--- a/core/java/android/app/Application.java
+++ b/core/java/android/app/Application.java
@@ -16,10 +16,14 @@
package android.app;
+import java.util.ArrayList;
+
import android.content.ComponentCallbacks;
+import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.res.Configuration;
+import android.os.Bundle;
/**
* Base class for those who need to maintain global application state. You can
@@ -36,10 +40,25 @@
* {@link android.content.Context#getApplicationContext() Context.getApplicationContext()}
* when first constructing the singleton.</p>
*/
-public class Application extends ContextWrapper implements ComponentCallbacks {
+public class Application extends ContextWrapper implements ComponentCallbacks2 {
+ private ArrayList<ComponentCallbacks> mComponentCallbacks =
+ new ArrayList<ComponentCallbacks>();
+ private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
+ new ArrayList<ActivityLifecycleCallbacks>();
+
/** @hide */
public LoadedApk mLoadedApk;
-
+
+ public interface ActivityLifecycleCallbacks {
+ void onActivityCreated(Activity activity, Bundle savedInstanceState);
+ void onActivityStarted(Activity activity);
+ void onActivityResumed(Activity activity);
+ void onActivityPaused(Activity activity);
+ void onActivityStopped(Activity activity);
+ void onActivitySaveInstanceState(Activity activity, Bundle outState);
+ void onActivityDestroyed(Activity activity);
+ }
+
public Application() {
super(null);
}
@@ -63,11 +82,59 @@
*/
public void onTerminate() {
}
-
+
public void onConfigurationChanged(Configuration newConfig) {
+ Object[] callbacks = collectComponentCallbacks();
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((ComponentCallbacks)callbacks[i]).onConfigurationChanged(newConfig);
+ }
+ }
}
-
+
public void onLowMemory() {
+ Object[] callbacks = collectComponentCallbacks();
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((ComponentCallbacks)callbacks[i]).onLowMemory();
+ }
+ }
+ }
+
+ public void onTrimMemory(int level) {
+ Object[] callbacks = collectComponentCallbacks();
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ Object c = callbacks[i];
+ if (c instanceof ComponentCallbacks2) {
+ ((ComponentCallbacks2)c).onTrimMemory(level);
+ }
+ }
+ }
+ }
+
+ public void registerComponentCallbacks(ComponentCallbacks callback) {
+ synchronized (mComponentCallbacks) {
+ mComponentCallbacks.add(callback);
+ }
+ }
+
+ public void unregisterComponentCallbacks(ComponentCallbacks callback) {
+ synchronized (mComponentCallbacks) {
+ mComponentCallbacks.remove(callback);
+ }
+ }
+
+ public void registerActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
+ synchronized (mActivityLifecycleCallbacks) {
+ mActivityLifecycleCallbacks.add(callback);
+ }
+ }
+
+ public void unregisterActivityLifecycleCallbacks(ActivityLifecycleCallbacks callback) {
+ synchronized (mActivityLifecycleCallbacks) {
+ mActivityLifecycleCallbacks.remove(callback);
+ }
}
// ------------------ Internal API ------------------
@@ -79,4 +146,89 @@
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
+
+ /* package */ void dispatchActivityCreated(Activity activity, Bundle savedInstanceState) {
+ Object[] callbacks = collectActivityLifecycleCallbacks();
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((ActivityLifecycleCallbacks)callbacks[i]).onActivityCreated(activity,
+ savedInstanceState);
+ }
+ }
+ }
+
+ /* package */ void dispatchActivityStarted(Activity activity) {
+ Object[] callbacks = collectActivityLifecycleCallbacks();
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStarted(activity);
+ }
+ }
+ }
+
+ /* package */ void dispatchActivityResumed(Activity activity) {
+ Object[] callbacks = collectActivityLifecycleCallbacks();
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((ActivityLifecycleCallbacks)callbacks[i]).onActivityResumed(activity);
+ }
+ }
+ }
+
+ /* package */ void dispatchActivityPaused(Activity activity) {
+ Object[] callbacks = collectActivityLifecycleCallbacks();
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((ActivityLifecycleCallbacks)callbacks[i]).onActivityPaused(activity);
+ }
+ }
+ }
+
+ /* package */ void dispatchActivityStopped(Activity activity) {
+ Object[] callbacks = collectActivityLifecycleCallbacks();
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((ActivityLifecycleCallbacks)callbacks[i]).onActivityStopped(activity);
+ }
+ }
+ }
+
+ /* package */ void dispatchActivitySaveInstanceState(Activity activity, Bundle outState) {
+ Object[] callbacks = collectActivityLifecycleCallbacks();
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((ActivityLifecycleCallbacks)callbacks[i]).onActivitySaveInstanceState(activity,
+ outState);
+ }
+ }
+ }
+
+ /* package */ void dispatchActivityDestroyed(Activity activity) {
+ Object[] callbacks = collectActivityLifecycleCallbacks();
+ if (callbacks != null) {
+ for (int i=0; i<callbacks.length; i++) {
+ ((ActivityLifecycleCallbacks)callbacks[i]).onActivityDestroyed(activity);
+ }
+ }
+ }
+
+ private Object[] collectComponentCallbacks() {
+ Object[] callbacks = null;
+ synchronized (mComponentCallbacks) {
+ if (mComponentCallbacks.size() > 0) {
+ callbacks = mComponentCallbacks.toArray();
+ }
+ }
+ return callbacks;
+ }
+
+ private Object[] collectActivityLifecycleCallbacks() {
+ Object[] callbacks = null;
+ synchronized (mActivityLifecycleCallbacks) {
+ if (mActivityLifecycleCallbacks.size() > 0) {
+ callbacks = mActivityLifecycleCallbacks.toArray();
+ }
+ }
+ return callbacks;
+ }
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index a99cec2..b4bdb2f 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1109,6 +1109,12 @@
throw new RuntimeException("Not supported in system context");
}
try {
+ IBinder token = getActivityToken();
+ if (token == null && (flags&BIND_AUTO_CREATE) == 0 && mPackageInfo != null
+ && mPackageInfo.getApplicationInfo().targetSdkVersion
+ < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+ flags |= BIND_WAIVE_PRIORITY;
+ }
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(),
service, service.resolveTypeIfNeeded(getContentResolver()),
diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java
index e2746d4..371e7ad 100644
--- a/core/java/android/app/Fragment.java
+++ b/core/java/android/app/Fragment.java
@@ -17,7 +17,7 @@
package android.app;
import android.animation.Animator;
-import android.content.ComponentCallbacks;
+import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
@@ -332,7 +332,7 @@
* pressing back will pop it to return the user to whatever previous state
* the activity UI was in.
*/
-public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener {
+public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListener {
private static final HashMap<String, Class<?>> sClassMap =
new HashMap<String, Class<?>>();
@@ -1182,6 +1182,10 @@
mCalled = true;
}
+ public void onTrimMemory(int level) {
+ mCalled = true;
+ }
+
/**
* Called when the view previously created by {@link #onCreateView} has
* been detached from the fragment. The next time the fragment needs
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 24550c5..c33ab2c 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1722,6 +1722,17 @@
}
}
+ public void dispatchTrimMemory(int level) {
+ if (mActive != null) {
+ for (int i=0; i<mAdded.size(); i++) {
+ Fragment f = mAdded.get(i);
+ if (f != null) {
+ f.onTrimMemory(level);
+ }
+ }
+ }
+ }
+
public boolean dispatchCreateOptionsMenu(Menu menu, MenuInflater inflater) {
boolean show = false;
ArrayList<Fragment> newMenus = null;
diff --git a/core/java/android/app/Service.java b/core/java/android/app/Service.java
index 4c21d04..ebde6e0 100644
--- a/core/java/android/app/Service.java
+++ b/core/java/android/app/Service.java
@@ -16,7 +16,7 @@
package android.app;
-import android.content.ComponentCallbacks;
+import android.content.ComponentCallbacks2;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ContextWrapper;
@@ -274,7 +274,7 @@
* {@sample development/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.java
* bind}
*/
-public abstract class Service extends ContextWrapper implements ComponentCallbacks {
+public abstract class Service extends ContextWrapper implements ComponentCallbacks2 {
private static final String TAG = "Service";
public Service() {
@@ -451,7 +451,10 @@
public void onLowMemory() {
}
-
+
+ public void onTrimMemory(int level) {
+ }
+
/**
* Return the communication channel to the service. May return null if
* clients can not bind to the service. The returned
diff --git a/core/java/android/app/backup/IBackupManager.aidl b/core/java/android/app/backup/IBackupManager.aidl
index d645ac3..c154296 100644
--- a/core/java/android/app/backup/IBackupManager.aidl
+++ b/core/java/android/app/backup/IBackupManager.aidl
@@ -185,7 +185,8 @@
*
* <p>Callers must hold the android.permission.BACKUP permission to use this method.
*/
- void acknowledgeFullBackupOrRestore(int token, boolean allow, in String password,
+ void acknowledgeFullBackupOrRestore(int token, boolean allow,
+ in String curPassword, in String encryptionPassword,
IFullBackupRestoreObserver observer);
/**
diff --git a/core/java/android/content/ComponentCallbacks.java b/core/java/android/content/ComponentCallbacks.java
index 37cc141..dad60b0 100644
--- a/core/java/android/content/ComponentCallbacks.java
+++ b/core/java/android/content/ComponentCallbacks.java
@@ -51,13 +51,4 @@
* The system will perform a gc for you after returning from this method.
*/
void onLowMemory();
-
- /** @hide */
- static final int TRIM_MEMORY_COMPLETE = 80;
-
- /** @hide */
- static final int TRIM_MEMORY_MODERATE = 50;
-
- /** @hide */
- static final int TRIM_MEMORY_BACKGROUND = 20;
}
diff --git a/core/java/android/content/ComponentCallbacks2.java b/core/java/android/content/ComponentCallbacks2.java
new file mode 100644
index 0000000..8b9f97c
--- /dev/null
+++ b/core/java/android/content/ComponentCallbacks2.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+/**
+ * Extended {@link ComponentCallbacks} interface with a new callback for
+ * finer-grained memory management.
+ */
+public interface ComponentCallbacks2 extends ComponentCallbacks {
+
+ /**
+ * Level for {@link #onTrimMemory(int)}: the process is nearing the end
+ * of the background LRU list, and if more memory isn't found soon it will
+ * be killed.
+ */
+ static final int TRIM_MEMORY_COMPLETE = 80;
+
+ /**
+ * Level for {@link #onTrimMemory(int)}: the process is around the middle
+ * of the background LRU list; freeing memory can help the system keep
+ * other processes running later in the list for better overall performance.
+ */
+ static final int TRIM_MEMORY_MODERATE = 60;
+
+ /**
+ * Level for {@link #onTrimMemory(int)}: the process has gone on to the
+ * LRU list. This is a good opportunity to clean up resources that can
+ * efficiently and quickly be re-built if the user returns to the app.
+ */
+ static final int TRIM_MEMORY_BACKGROUND = 40;
+
+ /**
+ * Level for {@link #onTrimMemory(int)}: the process had been showing
+ * a user interface, and is no longer doing so. Large allocations with
+ * the UI should be released at this point to allow memory to be better
+ * managed.
+ */
+ static final int TRIM_MEMORY_UI_HIDDEN = 20;
+
+ /**
+ * Called when the operating system has determined that it is a good
+ * time for a process to trim unneeded memory from its process. This will
+ * happen for example when it goes in the background and there is not enough
+ * memory to keep as many background processes running as desired.
+ *
+ * @param level The context of the trim, giving a hint of the amount of
+ * trimming the application may like to perform. May be
+ * {@link #TRIM_MEMORY_COMPLETE}, {@link #TRIM_MEMORY_MODERATE},
+ * {@link #TRIM_MEMORY_BACKGROUND}, or {@link #TRIM_MEMORY_UI_HIDDEN}.
+ */
+ void onTrimMemory(int level);
+}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 1a5c675..8057d4b 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -78,7 +78,7 @@
* ContentProvider instance, so subclasses don't have to worry about the details of
* cross-process calls.</p>
*/
-public abstract class ContentProvider implements ComponentCallbacks {
+public abstract class ContentProvider implements ComponentCallbacks2 {
private static final String TAG = "ContentProvider";
/*
@@ -491,6 +491,9 @@
public void onLowMemory() {
}
+ public void onTrimMemory(int level) {
+ }
+
/**
* Implement this to handle query requests from clients.
* This method can be called from multiple threads, as described in
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 2a02446..46712a9 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -107,12 +107,17 @@
* this still provides you with access to the service object while the
* service is created.
*
- * <p>Specifying this flag also tells the system to treat the service
- * as being as important as your own process -- that is, when deciding
- * which process should be killed to free memory, the service will only
- * be considered a candidate as long as the processes of any such bindings
- * is also a candidate to be killed. This is to avoid situations where
- * the service is being continually created and killed due to low memory.
+ * <p>Note that prior to {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH},
+ * not supplying this flag would also impact how important the system
+ * consider's the target service's process to be. When set, the only way
+ * for it to be raised was by binding from a service in which case it will
+ * only be important when that activity is in the foreground. Now to
+ * achieve this behavior you must explicitly supply the new flag
+ * {@link #BIND_ADJUST_WITH_ACTIVITY}. For compatibility, old applications
+ * that don't specify {@link #BIND_AUTO_CREATE} will automatically have
+ * the flags {@link #BIND_WAIVE_PRIORITY} and
+ * {@link #BIND_ADJUST_WITH_ACTIVITY} set for them in order to achieve
+ * the same result.
*/
public static final int BIND_AUTO_CREATE = 0x0001;
@@ -139,14 +144,48 @@
public static final int BIND_NOT_FOREGROUND = 0x0004;
/**
+ * Flag for {@link #bindService}: indicates that the client application
+ * binding to this service considers the service to be more important than
+ * the app itself. When set, the platform will try to have the out of
+ * memory kill the app before it kills the service it is bound to, though
+ * this is not guaranteed to be the case.
+ */
+ public static final int BIND_ABOVE_CLIENT = 0x0008;
+
+ /**
* 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
+ * whim it may have, and being more aggressive about making it a candidate
+ * to be killed (and restarted) if running for a long time.
*/
- public static final int BIND_ALLOW_OOM_MANAGEMENT = 0x0008;
+ public static final int BIND_ALLOW_OOM_MANAGEMENT = 0x0010;
+
+ /**
+ * Flag for {@link #bindService}: don't impact the scheduling or
+ * memory management priority of the target service's hosting process.
+ * Allows the service's process to be managed on the background LRU list
+ * just like a regular application process in the background.
+ */
+ public static final int BIND_WAIVE_PRIORITY = 0x0020;
+
+ /**
+ * Flag for {@link #bindService}: this service is very important to
+ * the client, so should be brought to the foreground process level
+ * when the client is. Normally a process can only be raised to the
+ * visibility level by a client, even if that client is in the foreground.
+ */
+ public static final int BIND_IMPORTANT = 0x0040;
+
+ /**
+ * Flag for {@link #bindService}: If binding from an activity, allow the
+ * target service's process importance to be raised based on whether the
+ * activity is visible to the user, regardless whether another flag is
+ * used to reduce the amount that the client process's overall importance
+ * is used to impact it.
+ */
+ public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0040;
/** Return an AssetManager instance for your application's package. */
public abstract AssetManager getAssets();
@@ -195,6 +234,25 @@
public abstract Context getApplicationContext();
/**
+ * Add a new {@link ComponentCallbacks} to the base application of the
+ * Context, which will be called at the same times as the ComponentCallbacks
+ * methods of activities and other components are called. Note that you
+ * <em>must</em> be sure to use {@link #unregisterComponentCallbacks} when
+ * appropriate in the future; this will not be removed for you.
+ */
+ public void registerComponentCallbacks(ComponentCallbacks callback) {
+ getApplicationContext().registerComponentCallbacks(callback);
+ }
+
+ /**
+ * Remove a {@link ComponentCallbacks} objec that was previously registered
+ * with {@link #registerComponentCallbacks(ComponentCallbacks)}.
+ */
+ public void unregisterComponentCallbacks(ComponentCallbacks callback) {
+ getApplicationContext().unregisterComponentCallbacks(callback);
+ }
+
+ /**
* Return a localized, styled CharSequence from the application's package's
* default string table.
*
@@ -1219,8 +1277,10 @@
* {@link IntentFilter} published by a service.
* @param conn Receives information as the service is started and stopped.
* @param flags Operation options for the binding. May be 0,
- * {@link #BIND_AUTO_CREATE}, {@link #BIND_DEBUG_UNBIND}, or
- * {@link #BIND_NOT_FOREGROUND}.
+ * {@link #BIND_AUTO_CREATE}, {@link #BIND_DEBUG_UNBIND},
+ * {@link #BIND_NOT_FOREGROUND}, {@link #BIND_ABOVE_CLIENT},
+ * {@link #BIND_ALLOW_OOM_MANAGEMENT}, or
+ * {@link #BIND_WAIVE_PRIORITY}.
* @return If you have successfully bound to the service, true is returned;
* false is returned if the connection is not made so you will not
* receive the service object.
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 132f3ba..75646fd 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -80,9 +80,9 @@
public LinkProperties(LinkProperties source) {
if (source != null) {
mIfaceName = source.getInterfaceName();
- mLinkAddresses = source.getLinkAddresses();
- mDnses = source.getDnses();
- mRoutes = source.getRoutes();
+ for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
+ for (InetAddress i : source.getDnses()) mDnses.add(i);
+ for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
mHttpProxy = (source.getHttpProxy() == null) ?
null : new ProxyProperties(source.getHttpProxy());
}
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 4e4923b..4e20358 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -17,7 +17,7 @@
package android.view;
-import android.content.ComponentCallbacks;
+import android.content.ComponentCallbacks2;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SurfaceTexture;
@@ -975,10 +975,10 @@
}
switch (level) {
- case ComponentCallbacks.TRIM_MEMORY_MODERATE:
+ case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_MODERATE);
break;
- case ComponentCallbacks.TRIM_MEMORY_COMPLETE:
+ case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
GLES20Canvas.flushCaches(GLES20Canvas.FLUSH_CACHES_FULL);
break;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 580d450..dd7eaa9 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1784,18 +1784,51 @@
public static final int OVER_SCROLL_NEVER = 2;
/**
- * View has requested the status bar to be visible (the default).
+ * View has requested the system UI (status bar) to be visible (the default).
*
* @see #setSystemUiVisibility(int)
*/
- public static final int STATUS_BAR_VISIBLE = 0;
+ public static final int SYSTEM_UI_FLAG_VISIBLE = 0;
/**
- * View has requested the status bar to be hidden.
+ * View has requested the system UI to enter an unobtrusive "low profile" mode.
+ *
+ * This is for use in games, book readers, video players, or any other "immersive" application
+ * where the usual system chrome is deemed too distracting.
+ *
+ * In low profile mode, the status bar and/or navigation icons may dim.
*
* @see #setSystemUiVisibility(int)
*/
- public static final int STATUS_BAR_HIDDEN = 0x00000001;
+ public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 0x00000001;
+
+ /**
+ * View has requested that the system navigation be temporarily hidden.
+ *
+ * This is an even less obtrusive state than that called for by
+ * {@link #SYSTEM_UI_FLAG_LOW_PROFILE}; on devices that draw essential navigation controls
+ * (Home, Back, and the like) on screen, <code>SYSTEM_UI_FLAG_HIDE_NAVIGATION</code> will cause
+ * those to disappear. This is useful (in conjunction with the
+ * {@link android.view.WindowManager.LayoutParams#FLAG_FULLSCREEN FLAG_FULLSCREEN} and
+ * {@link android.view.WindowManager.LayoutParams#FLAG_LAYOUT_IN_SCREEN FLAG_LAYOUT_IN_SCREEN}
+ * window flags) for displaying content using every last pixel on the display.
+ *
+ * There is a limitation: because navigation controls are so important, the least user
+ * interaction will cause them to reappear immediately.
+ *
+ * @see #setSystemUiVisibility(int)
+ */
+ public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002;
+
+ /**
+ * @deprecated Use {@link #SYSTEM_UI_FLAG_LOW_PROFILE} instead.
+ */
+ public static final int STATUS_BAR_HIDDEN = SYSTEM_UI_FLAG_LOW_PROFILE;
+
+ /**
+ * @deprecated Use {@link #SYSTEM_UI_FLAG_VISIBLE} instead.
+ */
+ public static final int STATUS_BAR_VISIBLE = SYSTEM_UI_FLAG_VISIBLE;
/**
* @hide
@@ -1889,7 +1922,7 @@
/**
* @hide
*/
- public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = STATUS_BAR_HIDDEN;
+ public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
/**
* Controls the over-scroll mode for this view.
@@ -1934,7 +1967,17 @@
* This view's request for the visibility of the status bar.
* @hide
*/
- @ViewDebug.ExportedProperty()
+ @ViewDebug.ExportedProperty(flagMapping = {
+ @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_LOW_PROFILE,
+ equals = SYSTEM_UI_FLAG_LOW_PROFILE,
+ name = "SYSTEM_UI_FLAG_LOW_PROFILE", outputIf = true),
+ @ViewDebug.FlagToString(mask = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
+ equals = SYSTEM_UI_FLAG_HIDE_NAVIGATION,
+ name = "SYSTEM_UI_FLAG_HIDE_NAVIGATION", outputIf = true),
+ @ViewDebug.FlagToString(mask = PUBLIC_STATUS_BAR_VISIBILITY_MASK,
+ equals = SYSTEM_UI_FLAG_VISIBLE,
+ name = "SYSTEM_UI_FLAG_VISIBLE", outputIf = true)
+ })
int mSystemUiVisibility;
/**
@@ -12538,7 +12581,8 @@
/**
* Request that the visibility of the status bar be changed.
- * @param visibility Either {@link #STATUS_BAR_VISIBLE} or {@link #STATUS_BAR_HIDDEN}.
+ * @param visibility Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
+ * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
*/
public void setSystemUiVisibility(int visibility) {
if (visibility != mSystemUiVisibility) {
@@ -12551,7 +12595,8 @@
/**
* Returns the status bar visibility that this view has requested.
- * @return Either {@link #STATUS_BAR_VISIBLE} or {@link #STATUS_BAR_HIDDEN}.
+ * @return Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
+ * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
*/
public int getSystemUiVisibility() {
return mSystemUiVisibility;
@@ -13654,7 +13699,8 @@
* Called when the status bar changes visibility because of a call to
* {@link View#setSystemUiVisibility(int)}.
*
- * @param visibility {@link #STATUS_BAR_VISIBLE} or {@link #STATUS_BAR_HIDDEN}.
+ * @param visibility Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
+ * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
*/
public void onSystemUiVisibilityChange(int visibility);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 0bd5a2a..b22ab7e 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -21,6 +21,7 @@
import android.app.ActivityManagerNative;
import android.content.ClipDescription;
import android.content.ComponentCallbacks;
+import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.CompatibilityInfo;
@@ -554,7 +555,7 @@
if (mThread != Thread.currentThread()) {
if (mAttachInfo.mHardwareRenderer != null &&
mAttachInfo.mHardwareRenderer.isEnabled()) {
- HardwareRenderer.trimMemory(ComponentCallbacks.TRIM_MEMORY_MODERATE);
+ HardwareRenderer.trimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE);
}
} else {
if (mAttachInfo.mHardwareRenderer != null &&
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index c11fc10..3916e86 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -30,7 +30,7 @@
void disable(int state);
void animateExpand();
void animateCollapse();
- void setLightsOn(boolean on);
+ void setSystemUiVisibility(int vis);
void topAppWindowChanged(boolean menuVisible);
void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
void setHardKeyboardStatus(boolean available, boolean enabled);
diff --git a/core/java/com/android/internal/textservice/ITextServicesManager.aidl b/core/java/com/android/internal/textservice/ITextServicesManager.aidl
index 2a045e3..eae1ac8 100644
--- a/core/java/com/android/internal/textservice/ITextServicesManager.aidl
+++ b/core/java/com/android/internal/textservice/ITextServicesManager.aidl
@@ -32,5 +32,6 @@
in ITextServicesSessionListener tsListener,
in ISpellCheckerSessionListener scListener);
oneway void finishSpellCheckerService(in ISpellCheckerSessionListener listener);
+ oneway void setCurrentSpellChecker(in SpellCheckerInfo info);
SpellCheckerInfo[] getEnabledSpellCheckers();
}
diff --git a/core/jni/android/graphics/NinePatchImpl.cpp b/core/jni/android/graphics/NinePatchImpl.cpp
index a3e36ee..579749a 100644
--- a/core/jni/android/graphics/NinePatchImpl.cpp
+++ b/core/jni/android/graphics/NinePatchImpl.cpp
@@ -160,6 +160,14 @@
return;
}
+ // if the nine patch is bigger than the dst on a given axis we cannot
+ // stretch properly so just draw the bitmap as best as possible and return
+ if (bitmap.width() >= bounds.width() || bitmap.height() >= bounds.height())
+ {
+ canvas->drawBitmapRect(bitmap, NULL, bounds, paint);
+ return;
+ }
+
// should try a quick-reject test before calling lockPixels
SkAutoLockPixels alp(bitmap);
diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp
index 4c84324..488b5c24 100644
--- a/core/jni/android_bluetooth_BluetoothSocket.cpp
+++ b/core/jni/android_bluetooth_BluetoothSocket.cpp
@@ -57,6 +57,9 @@
static const int RFCOMM_SO_SNDBUF = 70 * 1024; // 70 KB send buffer
+static void abortNative(JNIEnv *env, jobject obj);
+static void destroyNative(JNIEnv *env, jobject obj);
+
static struct asocket *get_socketData(JNIEnv *env, jobject obj) {
struct asocket *s =
(struct asocket *) env->GetIntField(obj, field_mSocketData);
@@ -172,6 +175,7 @@
socklen_t addr_sz;
struct sockaddr *addr;
struct asocket *s = get_socketData(env, obj);
+ int retry = 0;
if (!s)
return;
@@ -226,10 +230,30 @@
return;
}
+connect:
ret = asocket_connect(s, addr, addr_sz, -1);
LOGV("...connect(%d, %s) = %d (errno %d)",
s->fd, TYPE_AS_STR(type), ret, errno);
+ if (ret && errno == EALREADY && retry < 2) {
+ /* workaround for bug 5082381 (EALREADY on ACL collision):
+ * retry the connect. Unfortunately we have to create a new fd.
+ * It's not ideal to switch the fd underneath the object, but
+ * is currently safe */
+ LOGD("Hit bug 5082381 (EALREADY on ACL collision), trying workaround");
+ usleep(100000);
+ retry++;
+ abortNative(env, obj);
+ destroyNative(env, obj);
+ initSocketNative(env, obj);
+ if (env->ExceptionOccurred()) {
+ return;
+ }
+ goto connect;
+ }
+ if (!ret && retry > 0)
+ LOGD("...workaround ok");
+
if (ret)
jniThrowIOException(env, errno);
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 553632b..24d5d8d 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -21,7 +21,7 @@
<!-- Height of the status bar -->
<dimen name="status_bar_height">48dip</dimen>
<!-- Width and height of a single notification icon in the status bar -->
- <dimen name="status_bar_icon_size">32dip</dimen>
+ <dimen name="status_bar_icon_size">24dip</dimen>
<!-- Size of the giant number (unread count) in the notifications -->
<dimen name="status_bar_content_number_size">48sp</dimen>
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 3a3c082..3f4dace 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -132,10 +132,9 @@
LOCAL_STATIC_LIBRARIES += \
libstagefright_chromium_http \
- libchromium_net \
libwebcore \
-LOCAL_SHARED_LIBRARIES += libstlport
+LOCAL_SHARED_LIBRARIES += libstlport libchromium_net
include external/stlport/libstlport.mk
LOCAL_CPPFLAGS += -DCHROMIUM_AVAILABLE=1
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
index 08dcfae..3668b8c 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_backup.xml
@@ -21,7 +21,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:padding="10dp" >
+ android:padding="16dp" >
<TextView android:id="@+id/confirm_text"
android:layout_width="match_parent"
@@ -34,12 +34,26 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
- android:text="@string/backup_password_text" />
+ android:text="@string/current_password_text" />
<EditText android:id="@+id/password"
android:layout_below="@id/password_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:password="true" />
+
+ <TextView android:id="@+id/enc_password_desc"
+ android:layout_below="@id/password"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:text="@string/backup_enc_password_text" />
+
+ <EditText android:id="@+id/enc_password"
+ android:layout_below="@id/enc_password_desc"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
android:layout_marginBottom="30dp"
android:password="true" />
@@ -47,7 +61,7 @@
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginLeft="30dp"
- android:layout_below="@id/password"
+ android:layout_below="@id/enc_password"
android:layout_marginBottom="30dp" />
<Button android:id="@+id/button_allow"
diff --git a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
index 8b12ed4..38fcc496 100644
--- a/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
+++ b/packages/BackupRestoreConfirmation/res/layout/confirm_restore.xml
@@ -21,7 +21,7 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:padding="10dp" >
+ android:padding="16dp" >
<TextView android:id="@+id/confirm_text"
android:layout_width="match_parent"
@@ -34,7 +34,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
- android:text="@string/restore_password_text" />
+ android:text="@string/current_password_text" />
<EditText android:id="@+id/password"
android:layout_below="@id/password_desc"
@@ -43,11 +43,25 @@
android:layout_marginBottom="30dp"
android:password="true" />
+ <TextView android:id="@+id/enc_password_desc"
+ android:layout_below="@id/password"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="10dp"
+ android:text="@string/restore_enc_password_text" />
+
+ <EditText android:id="@+id/enc_password"
+ android:layout_below="@id/enc_password_desc"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="30dp"
+ android:password="true" />
+
<TextView android:id="@+id/package_name"
android:layout_width="match_parent"
android:layout_height="20dp"
android:layout_marginLeft="30dp"
- android:layout_below="@id/password"
+ android:layout_below="@id/enc_password"
android:layout_marginBottom="30dp" />
<Button android:id="@+id/button_allow"
diff --git a/packages/BackupRestoreConfirmation/res/values/strings.xml b/packages/BackupRestoreConfirmation/res/values/strings.xml
index 48a8df6..f022e57 100644
--- a/packages/BackupRestoreConfirmation/res/values/strings.xml
+++ b/packages/BackupRestoreConfirmation/res/values/strings.xml
@@ -30,10 +30,13 @@
<string name="deny_restore_button_label">Do not restore</string>
<!-- Text for message to user that they must enter their predefined backup password in order to perform this operation. -->
- <string name="backup_password_text">Please enter your predefined backup password below. The full backup will also be encrypted using this password:</string>
+ <string name="current_password_text">Please enter your current backup password below:</string>
+
+ <!-- Text for message to user that they can must enter an encryption password to use for the full backup operation. -->
+ <string name="backup_enc_password_text">Please enter a password to use for encrypting the full backup data. If this is left blank, your current backup password will be used:</string>
<!-- Text for message to user that they may optionally supply an encryption password to use for a full backup operation. -->
- <string name="backup_password_optional">If you wish to encrypt the full backup data, enter a password below:</string>
+ <string name="backup_enc_password_optional">If you wish to encrypt the full backup data, enter a password below:</string>
<!-- Text for message to user when performing a full restore operation, explaining that they must enter the password originally used to encrypt the full backup data. -->
- <string name="restore_password_text">If the backup data is encrypted, please enter the password below:</string>
+ <string name="restore_enc_password_text">If the restore data is encrypted, please enter the password below:</string>
</resources>
diff --git a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
index fad58b9..f65a62f 100644
--- a/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
+++ b/packages/BackupRestoreConfirmation/src/com/android/backupconfirm/BackupRestoreConfirmation.java
@@ -63,6 +63,8 @@
boolean mDidAcknowledge;
TextView mStatusView;
+ TextView mCurPassword;
+ TextView mEncPassword;
Button mAllowButton;
Button mDenyButton;
@@ -156,17 +158,17 @@
mAllowButton = (Button) findViewById(R.id.button_allow);
mDenyButton = (Button) findViewById(R.id.button_deny);
- // For full backup, we vary the password prompt text depending on whether one is predefined
- if (layoutId == R.layout.confirm_backup) {
- TextView pwDesc = (TextView) findViewById(R.id.password_desc);
- try {
- if (mBackupManager.hasBackupPassword()) {
- pwDesc.setText(R.string.backup_password_text);
- } else {
- pwDesc.setText(R.string.backup_password_optional);
- }
- } catch (RemoteException e) {
- // TODO: bail gracefully
+ mCurPassword = (TextView) findViewById(R.id.password);
+ mEncPassword = (TextView) findViewById(R.id.enc_password);
+ TextView curPwDesc = (TextView) findViewById(R.id.password_desc);
+
+ // We vary the password prompt depending on whether one is predefined
+ if (!haveBackupPassword()) {
+ curPwDesc.setVisibility(View.GONE);
+ mCurPassword.setVisibility(View.GONE);
+ if (layoutId == R.layout.confirm_backup) {
+ TextView encPwDesc = (TextView) findViewById(R.id.enc_password_desc);
+ encPwDesc.setText(R.string.backup_enc_password_optional);
}
}
@@ -204,15 +206,25 @@
mDidAcknowledge = true;
try {
- TextView pwView = (TextView) findViewById(R.id.password);
- mBackupManager.acknowledgeFullBackupOrRestore(mToken, allow,
- String.valueOf(pwView.getText()), mObserver);
+ mBackupManager.acknowledgeFullBackupOrRestore(mToken,
+ allow,
+ String.valueOf(mCurPassword.getText()),
+ String.valueOf(mEncPassword.getText()),
+ mObserver);
} catch (RemoteException e) {
// TODO: bail gracefully if we can't contact the backup manager
}
}
}
+ boolean haveBackupPassword() {
+ try {
+ return mBackupManager.hasBackupPassword();
+ } catch (RemoteException e) {
+ return true; // in the failure case, assume we need one
+ }
+ }
+
/**
* The observer binder for showing backup/restore progress. This binder just bounces
* the notifications onto the main thread.
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 5e48461..fe5b983 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -4,3 +4,12 @@
public void recentButtonClicked(android.view.View);
public void toggleLightsOut(android.view.View);
}
+
+-keep class com.android.systemui.statusbar.policy.KeyButtonView {
+ public float getDrawingAlpha();
+ public float getGlowAlpha();
+ public float getGlowScale();
+ public void setDrawingAlpha(float);
+ public void setGlowAlpha(float);
+ public void setGlowScale(float);
+}
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
index 7f96b03..ac5a97b 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png
deleted file mode 100644
index ac5a97b..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default_land.png
rename to packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png
deleted file mode 100644
index 8436f5a..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight_land.png
new file mode 100644
index 0000000..d050b1c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
index c43a019..a90dc9b 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png
deleted file mode 100644
index a90dc9b..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default_land.png
rename to packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png
deleted file mode 100644
index 83068a9..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
index 7af5454..d23f9b7 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png
deleted file mode 100644
index d23f9b7..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default_land.png
rename to packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png
deleted file mode 100644
index 56a4a1d..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
index 2d80bb9..cb3c433 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png
deleted file mode 100644
index cb3c433..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default_land.png
rename to packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png
deleted file mode 100644
index afc4057..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default.png
rename to packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default_land.png
rename to packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_pressed.png
deleted file mode 100644
index 83a8b26..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight_land.png
new file mode 100644
index 0000000..6f3f5fa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default.png
rename to packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default_land.png
rename to packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_pressed.png
deleted file mode 100644
index b090b95..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png
rename to packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default_land.png
rename to packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png
deleted file mode 100644
index 1affd8f..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default.png
rename to packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default_land.png
rename to packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_pressed.png
deleted file mode 100644
index c9724fc..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_pressed.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_default.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
similarity index 100%
rename from packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_default.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_default_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_default_land.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_sysbar_back_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight_land.png
new file mode 100644
index 0000000..97a07fa
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_default.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
similarity index 100%
rename from packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_default.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_default_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_default_land.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_sysbar_home_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_default.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
similarity index 100%
rename from packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_default.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_default_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_default_land.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_sysbar_menu_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_default.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
similarity index 100%
rename from packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_default.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_default_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
similarity index 100%
rename from packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_default_land.png
rename to packages/SystemUI/res/drawable-xhdpi/ic_sysbar_recent_land.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_back.xml b/packages/SystemUI/res/drawable/ic_sysbar_back.xml
deleted file mode 100644
index 327ccd8..0000000
--- a/packages/SystemUI/res/drawable/ic_sysbar_back.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_back_pressed" />
- <item android:drawable="@drawable/ic_sysbar_back_default" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_home.xml b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
deleted file mode 100644
index f4e585e..0000000
--- a/packages/SystemUI/res/drawable/ic_sysbar_home.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_home_pressed" />
- <item android:drawable="@drawable/ic_sysbar_home_default" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_menu.xml b/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
deleted file mode 100644
index 7a10607..0000000
--- a/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_menu_pressed" />
- <item android:drawable="@drawable/ic_sysbar_menu_default" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_recent.xml b/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
deleted file mode 100755
index 39a324b..0000000
--- a/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_recent_pressed" />
- <item android:drawable="@drawable/ic_sysbar_recent_default" />
-</selector>
-
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar.xml b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
index a2a6473..a204f17 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar.xml
@@ -32,6 +32,7 @@
android:id="@+id/bar_contents"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:clipChildren="false"
>
<!-- notification icons & panel access -->
@@ -50,6 +51,7 @@
android:layout_alignParentLeft="true"
systemui:keyCode="4"
android:contentDescription="@string/accessibility_back"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
<LinearLayout
android:id="@+id/navigationArea"
@@ -57,6 +59,8 @@
android:layout_height="match_parent"
android:layout_toRightOf="@+id/back"
android:orientation="horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_width="80dip"
@@ -64,12 +68,14 @@
android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
android:contentDescription="@string/accessibility_home"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
- <ImageView android:id="@+id/recent_apps"
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
android:layout_width="80dip"
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
android:contentDescription="@string/accessibility_menu"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_width="80dip"
@@ -78,6 +84,7 @@
systemui:keyCode="82"
android:visibility="invisible"
android:contentDescription="@string/accessibility_menu"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 5d7e8de..6732fee 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -35,6 +35,8 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
+ android:clipChildren="false"
+ android:clipToPadding="false"
>
<!-- navigation controls -->
@@ -42,47 +44,55 @@
android:layout_width="40dp"
android:layout_height="match_parent"
android:layout_weight="0"
+ android:visibility="invisible"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_width="80dp"
android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_back_default"
+ android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_back"
/>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
- android:contentDescription="@string/accessibility_back"
+ android:visibility="invisible"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_width="80dp"
android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_home_default"
+ android:src="@drawable/ic_sysbar_home"
systemui:keyCode="3"
android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_home"
/>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
- android:contentDescription="@string/accessibility_home"
+ android:visibility="invisible"
/>
- <ImageView android:id="@+id/recent_apps"
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
android:layout_width="80dp"
android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_recent_default"
+ android:src="@drawable/ic_sysbar_recent"
android:layout_weight="0"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:contentDescription="@string/accessibility_recent"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_width="40dp"
android:layout_height="match_parent"
- android:src="@drawable/ic_sysbar_menu_default"
+ android:src="@drawable/ic_sysbar_menu"
systemui:keyCode="82"
android:layout_weight="0"
android:visibility="invisible"
android:contentDescription="@string/accessibility_menu"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight"
/>
</LinearLayout>
@@ -106,55 +116,66 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
+ android:clipChildren="false"
+ android:clipToPadding="false"
>
<!-- navigation controls -->
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_height="40dp"
android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_menu_default_land"
+ android:src="@drawable/ic_sysbar_menu_land"
systemui:keyCode="82"
android:layout_weight="0"
android:visibility="invisible"
/>
- <ImageView android:id="@+id/recent_apps"
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
android:layout_height="80dp"
android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_recent_default_land"
+ android:src="@drawable/ic_sysbar_recent_land"
android:layout_weight="0"
+ android:contentDescription="@string/accessibility_recent"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
/>
<View
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1"
- android:contentDescription="@string/accessibility_menu"
+ android:visibility="invisible"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
android:layout_height="80dp"
android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_home_default_land"
+ android:src="@drawable/ic_sysbar_home_land"
systemui:keyCode="3"
android:layout_weight="0"
android:contentDescription="@string/accessibility_home"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
/>
<View
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1"
- android:contentDescription="@string/accessibility_back"
+ android:visibility="invisible"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_height="80dp"
android:layout_width="match_parent"
- android:src="@drawable/ic_sysbar_back_default_land"
+ android:src="@drawable/ic_sysbar_back_land"
systemui:keyCode="4"
android:layout_weight="0"
+ android:contentDescription="@string/accessibility_back"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
/>
- <View
+ <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
android:layout_height="40dp"
android:layout_width="match_parent"
+ android:src="@drawable/ic_sysbar_menu_land"
+ systemui:keyCode="82"
android:layout_weight="0"
+ android:visibility="invisible"
android:contentDescription="@string/accessibility_menu"
+ systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
/>
</LinearLayout>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 5291629..b2b6d50 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -17,6 +17,7 @@
<resources>
<declare-styleable name="KeyButtonView">
<attr name="keyCode" format="integer" />
+ <attr name="glowBackground" format="reference" />
</declare-styleable>
<declare-styleable name="ToggleSlider">
<attr name="text" format="string" />
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 5ca77fc..2b3118d 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -185,6 +185,8 @@
<string name="accessibility_home">Home</string>
<!-- Content description of the menu button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_menu">Menu</string>
+ <!-- Content description of the recents button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_recent">Recent applications</string>
<!-- Content description of the switch input method button for accessibility (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_ime_switch_button">Switch input method button.</string>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index eaffd1a..6ecfd94 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -131,9 +131,16 @@
return result;
}
- void invalidateGlobalRegion(View view) {
- RectF childBounds = new RectF(view.getLeft(), view.getTop(), view.getRight(), view
- .getBottom());
+ // invalidate the view's own bounds all the way up the view hierarchy
+ public static void invalidateGlobalRegion(View view) {
+ invalidateGlobalRegion(
+ view,
+ new RectF(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()));
+ }
+
+ // invalidate a rectangle relative to the view's coordinate system all the way up the view
+ // hierarchy
+ public static void invalidateGlobalRegion(View view, RectF childBounds) {
childBounds.offset(view.getX(), view.getY());
if (DEBUG_INVALIDATE)
Log.v(TAG, "-------------");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 62d7500..c91f513 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -54,7 +54,7 @@
private static final int OP_EXPAND = 1;
private static final int OP_COLLAPSE = 2;
- private static final int MSG_SET_LIGHTS_ON = 7 << MSG_SHIFT;
+ private static final int MSG_SET_SYSTEMUI_VISIBILITY = 7 << MSG_SHIFT;
private static final int MSG_TOP_APP_WINDOW_CHANGED = 8 << MSG_SHIFT;
private static final int MSG_SHOW_IME_BUTTON = 9 << MSG_SHIFT;
@@ -86,7 +86,7 @@
public void disable(int state);
public void animateExpand();
public void animateCollapse();
- public void setLightsOn(boolean on);
+ public void setSystemUiVisibility(int vis);
public void topAppWindowChanged(boolean visible);
public void setImeWindowStatus(IBinder token, int vis, int backDisposition);
public void setHardKeyboardStatus(boolean available, boolean enabled);
@@ -160,10 +160,10 @@
}
}
- public void setLightsOn(boolean on) {
+ public void setSystemUiVisibility(int vis) {
synchronized (mList) {
- mHandler.removeMessages(MSG_SET_LIGHTS_ON);
- mHandler.obtainMessage(MSG_SET_LIGHTS_ON, on ? 1 : 0, 0, null).sendToTarget();
+ mHandler.removeMessages(MSG_SET_SYSTEMUI_VISIBILITY);
+ mHandler.obtainMessage(MSG_SET_SYSTEMUI_VISIBILITY, vis, 0, null).sendToTarget();
}
}
@@ -259,8 +259,8 @@
mCallbacks.animateCollapse();
}
break;
- case MSG_SET_LIGHTS_ON:
- mCallbacks.setLightsOn(msg.arg1 != 0);
+ case MSG_SET_SYSTEMUI_VISIBILITY:
+ mCallbacks.setSystemUiVisibility(msg.arg1);
break;
case MSG_TOP_APP_WINDOW_CHANGED:
mCallbacks.topAppWindowChanged(msg.arg1 != 0);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
index ca75138..918d5a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBar.java
@@ -78,7 +78,7 @@
}
disable(switches[0]);
- setLightsOn(switches[1] != 0);
+ setSystemUiVisibility(switches[1]);
topAppWindowChanged(switches[2] != 0);
// StatusBarManagerService has a back up of IME token and it's restored here.
setImeWindowStatus(binders.get(0), switches[3], switches[4]);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 550fc57..2740898 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -17,11 +17,14 @@
package com.android.systemui.statusbar.phone;
import android.animation.Animator;
+import android.animation.AnimatorSet;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
+import android.content.res.Resources;
import android.os.ServiceManager;
import android.util.AttributeSet;
+import android.util.Slog;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -36,6 +39,9 @@
import com.android.systemui.R;
public class NavigationBarView extends LinearLayout {
+ final static boolean DEBUG = false;
+ final static String TAG = "NavigationBarView";
+
final static boolean DEBUG_DEADZONE = false;
final static boolean NAVBAR_ALWAYS_AT_RIGHT = true;
@@ -44,7 +50,12 @@
final Display mDisplay;
View mCurrentView = null;
View[] mRotatedViews = new View[4];
- Animator mLastAnimator = null;
+ AnimatorSet mLastAnimator = null;
+
+ int mBarSize;
+ boolean mVertical;
+
+ boolean mHidden;
public View getRecentsButton() {
return mCurrentView.findViewById(R.id.recent_apps);
@@ -56,37 +67,53 @@
public NavigationBarView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mHidden = false;
+
mDisplay = ((WindowManager)context.getSystemService(
Context.WINDOW_SERVICE)).getDefaultDisplay();
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
- //setLayerType(View.LAYER_TYPE_HARDWARE, null);
-
- setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
- @Override
- public void onSystemUiVisibilityChange(int visibility) {
- boolean on = (visibility == View.STATUS_BAR_VISIBLE);
- android.util.Log.d("NavigationBarView", "LIGHTS "
- + (on ? "ON" : "OUT"));
- setLights(on);
- }
- });
+ final Resources res = mContext.getResources();
+ mBarSize = res.getDimensionPixelSize(R.dimen.navigation_bar_size);
+ mVertical = false;
}
- private void setLights(final boolean on) {
+ public void setHidden(final boolean hide) {
+ if (hide == mHidden) return;
+
+ mHidden = hide;
+ Slog.d(TAG,
+ (hide ? "HIDING" : "SHOWING") + " navigation bar");
+
float oldAlpha = mCurrentView.getAlpha();
- android.util.Log.d("NavigationBarView", "animating alpha: " + oldAlpha + " -> "
- + (on ? 1f : 0f));
+ if (DEBUG) {
+ Slog.d(TAG, "animating alpha: " + oldAlpha + " -> "
+ + (!hide ? 1f : 0f));
+ }
if (mLastAnimator != null && mLastAnimator.isRunning()) mLastAnimator.cancel();
- mLastAnimator = ObjectAnimator.ofFloat(mCurrentView, "alpha", oldAlpha, on ? 1f : 0f)
- .setDuration(on ? 250 : 1500);
+ if (!hide) {
+ setVisibility(View.VISIBLE);
+ }
+
+ // play us off, animatorset
+ mLastAnimator = new AnimatorSet();
+ mLastAnimator.playTogether(
+ ObjectAnimator.ofFloat(mCurrentView, "alpha", hide ? 0f : 1f),
+ ObjectAnimator.ofFloat(mCurrentView,
+ mVertical ? "translationX" : "translationY",
+ hide ? mBarSize : 0)
+ );
+ mLastAnimator.setDuration(!hide ? 250 : 1000);
mLastAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator _a) {
mLastAnimator = null;
+ if (hide) {
+ setVisibility(View.INVISIBLE);
+ }
}
});
mLastAnimator.start();
@@ -108,7 +135,7 @@
@Override
public boolean onTouchEvent(MotionEvent ev) {
// immediately bring up the lights
- setLights(true);
+ setHidden(false);
return false; // pass it on
}
@@ -119,11 +146,14 @@
}
mCurrentView = mRotatedViews[rot];
mCurrentView.setVisibility(View.VISIBLE);
+ mVertical = (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270);
if (DEBUG_DEADZONE) {
mCurrentView.findViewById(R.id.deadzone).setBackgroundColor(0x808080FF);
}
- android.util.Log.d("NavigationBarView", "reorient(): rot=" + mDisplay.getRotation());
+ if (DEBUG) {
+ Slog.d(TAG, "reorient(): rot=" + mDisplay.getRotation());
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 21b774c..f8ceb8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -198,6 +198,9 @@
// for disabling the status bar
int mDisabled = 0;
+ // tracking calls to View.setSystemUiVisibility()
+ int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
+
private class ExpandedDialog extends Dialog {
ExpandedDialog(Context context) {
super(context, com.android.internal.R.style.Theme_Light_NoTitleBar);
@@ -253,20 +256,33 @@
mIntruderAlertView.setVisibility(View.GONE);
mIntruderAlertView.setClickable(true);
+ PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context,
+ R.layout.status_bar, null);
+ sb.mService = this;
+ mStatusBarView = sb;
+
try {
boolean showNav = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar);
if (showNav) {
mNavigationBarView =
(NavigationBarView) View.inflate(context, R.layout.navigation_bar, null);
+
+ sb.setOnSystemUiVisibilityChangeListener(
+ new View.OnSystemUiVisibilityChangeListener() {
+ @Override
+ public void onSystemUiVisibilityChange(int visibility) {
+ if (DEBUG) {
+ Slog.d(TAG, "systemUi: " + visibility);
+ }
+ boolean hide = (0 != (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION));
+ mNavigationBarView.setHidden(hide);
+ }
+ });
}
} catch (Resources.NotFoundException ex) {
// no nav bar for you
}
- PhoneStatusBarView sb = (PhoneStatusBarView)View.inflate(context,
- R.layout.status_bar, null);
- sb.mService = this;
-
// figure out which pixel-format to use for the status bar.
mPixelFormat = PixelFormat.TRANSLUCENT;
Drawable bg = sb.getBackground();
@@ -274,7 +290,6 @@
mPixelFormat = bg.getOpacity();
}
- mStatusBarView = sb;
mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);
mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);
mIcons = (LinearLayout)sb.findViewById(R.id.icons);
@@ -649,8 +664,10 @@
if (notification.notification.largeIcon != null) {
oldEntry.largeIcon.setImageBitmap(notification.notification.largeIcon);
} else {
- oldEntry.largeIcon.getLayoutParams().width = 0;
- oldEntry.largeIcon.setVisibility(View.INVISIBLE);
+ if (oldEntry.largeIcon != null) {
+ oldEntry.largeIcon.getLayoutParams().width = 0;
+ oldEntry.largeIcon.setVisibility(View.INVISIBLE);
+ }
}
}
@@ -1275,22 +1292,31 @@
return false;
}
- public void setLightsOn(boolean on) {
- Log.v(TAG, "lights " + (on ? "on" : "off"));
- if (!on) {
- // All we do for "lights out" mode on a phone is hide the status bar,
- // which the window manager does. But we do need to hide the windowshade
- // on our own.
- animateCollapse();
+ @Override // CommandQueue
+ public void setSystemUiVisibility(int vis) {
+ if (vis != mSystemUiVisibility) {
+ mSystemUiVisibility = vis;
+
+ if (0 != (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
+ animateCollapse();
+ }
+
+ notifyUiVisibilityChanged();
}
- notifyLightsChanged(on);
}
- private void notifyLightsChanged(boolean shown) {
+ public void setLightsOn(boolean on) {
+ Log.v(TAG, "setLightsOn(" + on + ")");
+ if (on) {
+ setSystemUiVisibility(mSystemUiVisibility & ~View.SYSTEM_UI_FLAG_LOW_PROFILE);
+ } else {
+ setSystemUiVisibility(mSystemUiVisibility | View.SYSTEM_UI_FLAG_LOW_PROFILE);
+ }
+ }
+
+ private void notifyUiVisibilityChanged() {
try {
- Slog.d(TAG, "lights " + (shown?"on":"out"));
- mWindowManager.statusBarVisibilityChanged(
- shown ? View.STATUS_BAR_VISIBLE : View.STATUS_BAR_HIDDEN);
+ mWindowManager.statusBarVisibilityChanged(mSystemUiVisibility);
} catch (RemoteException ex) {
}
}
@@ -1715,10 +1741,12 @@
}
}
+ // The user is not allowed to get stuck without navigation UI. Upon the slightest user
+ // interaction we bring the navigation back.
public void userActivity() {
- try {
- mBarService.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
- } catch (RemoteException ex) { }
+ if (mNavigationBarView != null) {
+ mNavigationBarView.setHidden(false);
+ }
}
public void toggleRecentApps() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index c82220d..38a1029 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -16,10 +16,15 @@
package com.android.systemui.statusbar.policy;
+import android.animation.Animator;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
+import android.graphics.Canvas;
+import android.graphics.RectF;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.ServiceManager;
@@ -33,7 +38,9 @@
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
+import android.view.View;
import android.view.ViewConfiguration;
+import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RemoteViews.RemoteView;
@@ -48,18 +55,25 @@
int mCode;
int mRepeat;
int mTouchSlop;
+ Drawable mGlowBG;
+ float mGlowAlpha = 0f, mGlowScale = 1f, mDrawingAlpha = 1f;
Runnable mCheckLongPress = new Runnable() {
public void run() {
if (isPressed()) {
- mRepeat++;
- sendEvent(KeyEvent.ACTION_DOWN,
- KeyEvent.FLAG_FROM_SYSTEM
- | KeyEvent.FLAG_VIRTUAL_HARD_KEY
- | KeyEvent.FLAG_LONG_PRESS);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
- //playSoundEffect(SoundEffectConstants.CLICK);
+ if (mCode != 0) {
+ mRepeat++;
+ sendEvent(KeyEvent.ACTION_DOWN,
+ KeyEvent.FLAG_FROM_SYSTEM
+ | KeyEvent.FLAG_VIRTUAL_HARD_KEY
+ | KeyEvent.FLAG_LONG_PRESS);
+
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
+ } else {
+ // Just an old-fashioned ImageView
+ performLongClick();
+ }
}
}
};
@@ -75,8 +89,10 @@
defStyle, 0);
mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0);
- if (mCode == 0) {
- Slog.w(TAG, "KeyButtonView without key code id=0x" + Integer.toHexString(getId()));
+
+ mGlowBG = a.getDrawable(R.styleable.KeyButtonView_glowBackground);
+ if (mGlowBG != null) {
+ mDrawingAlpha = 0.5f;
}
a.recycle();
@@ -88,6 +104,99 @@
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
+ @Override
+ protected void onDraw(Canvas canvas) {
+ if (mGlowBG != null) {
+ canvas.save();
+ final int w = getWidth();
+ final int h = getHeight();
+ canvas.scale(mGlowScale, mGlowScale, w*0.5f, h*0.5f);
+ mGlowBG.setBounds(0, 0, w, h);
+ mGlowBG.setAlpha((int)(mGlowAlpha * 255));
+ mGlowBG.draw(canvas);
+ canvas.restore();
+
+ canvas.saveLayerAlpha(null, (int)(mDrawingAlpha * 255), Canvas.ALL_SAVE_FLAG);
+ }
+ super.onDraw(canvas);
+ if (mGlowBG != null) {
+ canvas.restore();
+ }
+ }
+
+ public float getDrawingAlpha() {
+ if (mGlowBG == null) return 0;
+ return mDrawingAlpha;
+ }
+
+ public void setDrawingAlpha(float x) {
+ if (mGlowBG == null) return;
+ mDrawingAlpha = x;
+ invalidate();
+ }
+
+ public float getGlowAlpha() {
+ if (mGlowBG == null) return 0;
+ return mGlowAlpha;
+ }
+
+ public void setGlowAlpha(float x) {
+ if (mGlowBG == null) return;
+ mGlowAlpha = x;
+ invalidate();
+ }
+
+ public float getGlowScale() {
+ if (mGlowBG == null) return 0;
+ return mGlowScale;
+ }
+
+ public void setGlowScale(float x) {
+ if (mGlowBG == null) return;
+ mGlowScale = x;
+ final float w = getWidth();
+ final float h = getHeight();
+ if (x < 1.0f) {
+ invalidate();
+ } else {
+ final float rx = (w * (x - 1.0f)) / 2.0f;
+ final float ry = (h * (x - 1.0f)) / 2.0f;
+ com.android.systemui.SwipeHelper.invalidateGlobalRegion(
+ this,
+ new RectF(getLeft() - rx,
+ getTop() - ry,
+ getRight() + rx,
+ getBottom() + ry));
+ }
+ }
+
+ public void setPressed(boolean pressed) {
+ if (mGlowBG != null) {
+ if (pressed != isPressed()) {
+ AnimatorSet as = new AnimatorSet();
+ if (pressed) {
+ if (mGlowScale < 1.7f) mGlowScale = 1.7f;
+ if (mGlowAlpha < 0.5f) mGlowAlpha = 0.5f;
+ setDrawingAlpha(1f);
+ as.playTogether(
+ ObjectAnimator.ofFloat(this, "glowAlpha", 1f),
+ ObjectAnimator.ofFloat(this, "glowScale", 1.8f)
+ );
+ as.setDuration(50);
+ } else {
+ as.playTogether(
+ ObjectAnimator.ofFloat(this, "glowAlpha", 0f),
+ ObjectAnimator.ofFloat(this, "glowScale", 1f),
+ ObjectAnimator.ofFloat(this, "drawingAlpha", 0.5f)
+ );
+ as.setDuration(500);
+ }
+ as.start();
+ }
+ }
+ super.setPressed(pressed);
+ }
+
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
int x, y;
@@ -131,12 +240,18 @@
mSending = false;
final int flags = KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY;
removeCallbacks(mCheckLongPress);
- if (doIt) {
- sendEvent(KeyEvent.ACTION_UP, flags);
- sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
- playSoundEffect(SoundEffectConstants.CLICK);
+
+ if (mCode != 0) {
+ if (doIt) {
+ sendEvent(KeyEvent.ACTION_UP, flags);
+ sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
+ playSoundEffect(SoundEffectConstants.CLICK);
+ } else {
+ sendEvent(KeyEvent.ACTION_UP, flags | KeyEvent.FLAG_CANCELED);
+ }
} else {
- sendEvent(KeyEvent.ACTION_UP, flags | KeyEvent.FLAG_CANCELED);
+ // no key code, just a regular ImageView
+ if (doIt) performClick();
}
}
break;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 96f6e2f..c6e546e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -176,6 +176,8 @@
private InputMethodsPanel mInputMethodsPanel;
private CompatModePanel mCompatModePanel;
+ int mSystemUiVisibility = 0;
+
public Context getContext() { return mContext; }
protected void addPanelWindows() {
@@ -729,14 +731,16 @@
if (DEBUG) Slog.d(TAG, "hiding shadows (lights on)");
mBarContents.setVisibility(View.VISIBLE);
mShadow.setVisibility(View.GONE);
- notifyLightsChanged(true);
+ mSystemUiVisibility &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
+ notifyUiVisibilityChanged();
break;
case MSG_HIDE_CHROME:
if (DEBUG) Slog.d(TAG, "showing shadows (lights out)");
animateCollapse();
mBarContents.setVisibility(View.GONE);
mShadow.setVisibility(View.VISIBLE);
- notifyLightsChanged(false);
+ mSystemUiVisibility |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
+ notifyUiVisibilityChanged();
break;
case MSG_STOP_TICKER:
mTicker.halt();
@@ -1025,17 +1029,40 @@
mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PEEK);
}
- // called by StatusBar
- @Override
+ private void notifyUiVisibilityChanged() {
+ try {
+ mWindowManager.statusBarVisibilityChanged(mSystemUiVisibility);
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override // CommandQueue
+ public void setSystemUiVisibility(int vis) {
+ if (vis != mSystemUiVisibility) {
+ mSystemUiVisibility = vis;
+
+ mHandler.removeMessages(MSG_HIDE_CHROME);
+ mHandler.removeMessages(MSG_SHOW_CHROME);
+ mHandler.sendEmptyMessage(0 == (vis & View.SYSTEM_UI_FLAG_LOW_PROFILE)
+ ? MSG_SHOW_CHROME : MSG_HIDE_CHROME);
+
+ notifyUiVisibilityChanged();
+ }
+ }
+
public void setLightsOn(boolean on) {
// Policy note: if the frontmost activity needs the menu key, we assume it is a legacy app
// that can't handle lights-out mode.
if (mMenuButton.getVisibility() == View.VISIBLE) {
on = true;
}
- mHandler.removeMessages(MSG_HIDE_CHROME);
- mHandler.removeMessages(MSG_SHOW_CHROME);
- mHandler.sendEmptyMessage(on ? MSG_SHOW_CHROME : MSG_HIDE_CHROME);
+
+ Slog.v(TAG, "setLightsOn(" + on + ")");
+ if (on) {
+ setSystemUiVisibility(mSystemUiVisibility & ~View.SYSTEM_UI_FLAG_LOW_PROFILE);
+ } else {
+ setSystemUiVisibility(mSystemUiVisibility | View.SYSTEM_UI_FLAG_LOW_PROFILE);
+ }
}
public void topAppWindowChanged(boolean showMenu) {
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index 3ec2a96..bdd8938 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -307,7 +307,8 @@
public ParcelFileDescriptor fd;
public final AtomicBoolean latch;
public IFullBackupRestoreObserver observer;
- public String password; // filled in by the confirmation step
+ public String curPassword; // filled in by the confirmation step
+ public String encryptPassword;
FullParams() {
latch = new AtomicBoolean(false);
@@ -458,8 +459,8 @@
{
FullBackupParams params = (FullBackupParams)msg.obj;
(new PerformFullBackupTask(params.fd, params.observer, params.includeApks,
- params.includeShared, params.password, params.allApps, params.packages,
- params.latch)).run();
+ params.includeShared, params.curPassword, params.encryptPassword,
+ params.allApps, params.packages, params.latch)).run();
break;
}
@@ -476,7 +477,7 @@
case MSG_RUN_FULL_RESTORE:
{
FullRestoreParams params = (FullRestoreParams)msg.obj;
- (new PerformFullRestoreTask(params.fd, params.password,
+ (new PerformFullRestoreTask(params.fd, params.curPassword, params.encryptPassword,
params.observer, params.latch)).run();
break;
}
@@ -1908,7 +1909,8 @@
boolean mIncludeShared;
boolean mAllApps;
String[] mPackages;
- String mUserPassword;
+ String mCurrentPassword;
+ String mEncryptPassword;
AtomicBoolean mLatchObject;
File mFilesDir;
File mManifestFile;
@@ -1963,15 +1965,25 @@
}
PerformFullBackupTask(ParcelFileDescriptor fd, IFullBackupRestoreObserver observer,
- boolean includeApks, boolean includeShared, String password,
- boolean doAllApps, String[] packages, AtomicBoolean latch) {
+ boolean includeApks, boolean includeShared, String curPassword,
+ String encryptPassword, boolean doAllApps, String[] packages,
+ AtomicBoolean latch) {
mOutputFile = fd;
mObserver = observer;
mIncludeApks = includeApks;
mIncludeShared = includeShared;
mAllApps = doAllApps;
mPackages = packages;
- mUserPassword = password;
+ mCurrentPassword = curPassword;
+ // when backing up, if there is a current backup password, we require that
+ // the user use a nonempty encryption password as well. if one is supplied
+ // in the UI we use that, but if the UI was left empty we fall back to the
+ // current backup password (which was supplied by the user as well).
+ if (encryptPassword == null || "".equals(encryptPassword)) {
+ mEncryptPassword = curPassword;
+ } else {
+ mEncryptPassword = encryptPassword;
+ }
mLatchObject = latch;
mFilesDir = new File("/data/system");
@@ -2016,7 +2028,7 @@
PackageInfo pkg = null;
try {
- boolean encrypting = (mUserPassword != null && mUserPassword.length() > 0);
+ boolean encrypting = (mEncryptPassword != null && mEncryptPassword.length() > 0);
boolean compressing = COMPRESS_FULL_BACKUPS;
OutputStream finalOutput = ofstream;
@@ -2057,7 +2069,7 @@
// Verify that the given password matches the currently-active
// backup password, if any
if (hasBackupPassword()) {
- if (!passwordMatchesSaved(mUserPassword, PBKDF2_HASH_ROUNDS)) {
+ if (!passwordMatchesSaved(mCurrentPassword, PBKDF2_HASH_ROUNDS)) {
if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
return;
}
@@ -2122,7 +2134,7 @@
OutputStream ofstream) throws Exception {
// User key will be used to encrypt the master key.
byte[] newUserSalt = randomBytes(PBKDF2_SALT_SIZE);
- SecretKey userKey = buildPasswordKey(mUserPassword, newUserSalt,
+ SecretKey userKey = buildPasswordKey(mEncryptPassword, newUserSalt,
PBKDF2_HASH_ROUNDS);
// the master key is random for each backup
@@ -2445,7 +2457,8 @@
class PerformFullRestoreTask implements Runnable {
ParcelFileDescriptor mInputFile;
- String mUserPassword;
+ String mCurrentPassword;
+ String mDecryptPassword;
IFullBackupRestoreObserver mObserver;
AtomicBoolean mLatchObject;
IBackupAgent mAgent;
@@ -2469,10 +2482,11 @@
// Packages we've already wiped data on when restoring their first file
final HashSet<String> mClearedPackages = new HashSet<String>();
- PerformFullRestoreTask(ParcelFileDescriptor fd, String password,
+ PerformFullRestoreTask(ParcelFileDescriptor fd, String curPassword, String decryptPassword,
IFullBackupRestoreObserver observer, AtomicBoolean latch) {
mInputFile = fd;
- mUserPassword = password;
+ mCurrentPassword = curPassword;
+ mDecryptPassword = decryptPassword;
mObserver = observer;
mLatchObject = latch;
mAgent = null;
@@ -2531,6 +2545,13 @@
FileInputStream rawInStream = null;
DataInputStream rawDataIn = null;
try {
+ if (hasBackupPassword()) {
+ if (!passwordMatchesSaved(mCurrentPassword, PBKDF2_HASH_ROUNDS)) {
+ if (DEBUG) Slog.w(TAG, "Backup password mismatch; aborting");
+ return;
+ }
+ }
+
mBytes = 0;
byte[] buffer = new byte[32 * 1024];
rawInStream = new FileInputStream(mInputFile.getFileDescriptor());
@@ -2557,7 +2578,7 @@
if (s.equals("none")) {
// no more header to parse; we're good to go
okay = true;
- } else if (mUserPassword != null && mUserPassword.length() > 0) {
+ } else if (mDecryptPassword != null && mDecryptPassword.length() > 0) {
preCompressStream = decodeAesHeaderAndInitialize(s, rawInStream);
if (preCompressStream != null) {
okay = true;
@@ -2635,7 +2656,7 @@
// decrypt the master key blob
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
- SecretKey userKey = buildPasswordKey(mUserPassword, userSalt,
+ SecretKey userKey = buildPasswordKey(mDecryptPassword, userSalt,
rounds);
byte[] IV = hexToByteArray(userIvHex);
IvParameterSpec ivSpec = new IvParameterSpec(IV);
@@ -4453,7 +4474,7 @@
// is used to require a user-facing disclosure about the operation.
@Override
public void acknowledgeFullBackupOrRestore(int token, boolean allow,
- String password, IFullBackupRestoreObserver observer) {
+ String curPassword, String encPpassword, IFullBackupRestoreObserver observer) {
if (DEBUG) Slog.d(TAG, "acknowledgeFullBackupOrRestore : token=" + token
+ " allow=" + allow);
@@ -4472,12 +4493,14 @@
mFullConfirmations.delete(token);
if (allow) {
- params.observer = observer;
- params.password = password;
final int verb = params instanceof FullBackupParams
? MSG_RUN_FULL_BACKUP
: MSG_RUN_FULL_RESTORE;
+ params.observer = observer;
+ params.curPassword = curPassword;
+ params.encryptPassword = encPpassword;
+
if (DEBUG) Slog.d(TAG, "Sending conf message with verb " + verb);
mWakelock.acquire();
Message msg = mBackupHandler.obtainMessage(verb, params);
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 9a9cc8f..2a724d4 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -2484,7 +2484,7 @@
synchronized (this) {
if (mDefaultProxy != null && mDefaultProxy.equals(proxy)) return;
if (mDefaultProxy == proxy) return;
- if (!TextUtils.isEmpty(proxy.getHost())) {
+ if (proxy != null && !TextUtils.isEmpty(proxy.getHost())) {
mDefaultProxy = proxy;
} else {
mDefaultProxy = null;
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index 4ced83c..ca3b12d 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -69,8 +69,8 @@
int mDisabled = 0;
Object mLock = new Object();
- // We usually call it lights out mode, but double negatives are annoying
- boolean mLightsOn = true;
+ // encompasses lights-out mode and other flags defined on View
+ int mSystemUiVisibility = 0;
boolean mMenuVisible = false;
int mImeWindowVis = 0;
int mImeBackDisposition;
@@ -301,22 +301,23 @@
// also allows calls from window manager which is in this process.
enforceStatusBarService();
+ if (SPEW) Slog.d(TAG, "setSystemUiVisibility(" + vis + ")");
+
synchronized (mLock) {
- final boolean lightsOn = (vis & View.STATUS_BAR_HIDDEN) == 0;
- updateLightsOnLocked(lightsOn);
+ updateUiVisibilityLocked(vis);
disableLocked(vis & StatusBarManager.DISABLE_MASK, mSysUiVisToken,
"WindowManager.LayoutParams");
}
}
- private void updateLightsOnLocked(final boolean lightsOn) {
- if (mLightsOn != lightsOn) {
- mLightsOn = lightsOn;
+ private void updateUiVisibilityLocked(final int vis) {
+ if (mSystemUiVisibility != vis) {
+ mSystemUiVisibility = vis;
mHandler.post(new Runnable() {
public void run() {
if (mBar != null) {
try {
- mBar.setLightsOn(lightsOn);
+ mBar.setSystemUiVisibility(vis);
} catch (RemoteException ex) {
}
}
@@ -392,7 +393,7 @@
}
synchronized (mLock) {
switches[0] = gatherDisableActionsLocked();
- switches[1] = mLightsOn ? 1 : 0;
+ switches[1] = mSystemUiVisibility;
switches[2] = mMenuVisible ? 1 : 0;
switches[3] = mImeWindowVis;
switches[4] = mImeBackDisposition;
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index b2d9917..837778e 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -73,6 +73,16 @@
synchronized (mSpellCheckerMap) {
buildSpellCheckerMapLocked(context, mSpellCheckerList, mSpellCheckerMap);
}
+ SpellCheckerInfo sci = getCurrentSpellChecker(null);
+ if (sci == null) {
+ sci = findAvailSpellCheckerLocked(null, null);
+ if (sci != null) {
+ // Set the current spell checker if there is one or more spell checkers
+ // available. In this case, "sci" is the first one in the available spell
+ // checkers.
+ setCurrentSpellCheckerLocked(sci);
+ }
+ }
}
private class TextServicesMonitor extends PackageMonitor {
@@ -87,10 +97,10 @@
final int change = isPackageDisappearing(packageName);
if (change == PACKAGE_PERMANENT_CHANGE || change == PACKAGE_TEMPORARY_CHANGE) {
// Package disappearing
- setCurrentSpellChecker(findAvailSpellCheckerLocked(null, packageName));
+ setCurrentSpellCheckerLocked(findAvailSpellCheckerLocked(null, packageName));
} else if (isPackageModified(packageName)) {
// Package modified
- setCurrentSpellChecker(findAvailSpellCheckerLocked(null, packageName));
+ setCurrentSpellCheckerLocked(findAvailSpellCheckerLocked(null, packageName));
}
}
}
@@ -160,13 +170,7 @@
Slog.w(TAG, "getCurrentSpellChecker: " + curSpellCheckerId);
}
if (TextUtils.isEmpty(curSpellCheckerId)) {
- final SpellCheckerInfo sci = findAvailSpellCheckerLocked(null, null);
- if (sci == null) return null;
- // Set the current spell checker if there is one or more spell checkers
- // available. In this case, "sci" is the first one in the available spell
- // checkers.
- setCurrentSpellChecker(sci);
- return sci;
+ return null;
}
return mSpellCheckerMap.get(curSpellCheckerId);
}
@@ -187,12 +191,13 @@
if (!mSpellCheckerMap.containsKey(sciId)) {
return;
}
+ final int uid = Binder.getCallingUid();
if (mSpellCheckerBindGroups.containsKey(sciId)) {
final SpellCheckerBindGroup bindGroup = mSpellCheckerBindGroups.get(sciId);
if (bindGroup != null) {
final InternalDeathRecipient recipient =
mSpellCheckerBindGroups.get(sciId).addListener(
- tsListener, locale, scListener);
+ tsListener, locale, scListener, uid);
if (recipient == null) {
if (DBG) {
Slog.w(TAG, "Didn't create a death recipient.");
@@ -204,14 +209,22 @@
bindGroup.removeAll();
} else if (bindGroup.mSpellChecker != null) {
if (DBG) {
- Slog.w(TAG, "Existing bind found. Return a spell checker session now.");
+ Slog.w(TAG, "Existing bind found. Return a spell checker session now. "
+ + "Listeners count = " + bindGroup.mListeners.size());
}
try {
final ISpellCheckerSession session =
bindGroup.mSpellChecker.getISpellCheckerSession(
recipient.mScLocale, recipient.mScListener);
- tsListener.onServiceConnected(session);
- return;
+ if (session != null) {
+ tsListener.onServiceConnected(session);
+ return;
+ } else {
+ if (DBG) {
+ Slog.w(TAG, "Existing bind already expired. ");
+ }
+ bindGroup.removeAll();
+ }
} catch (RemoteException e) {
Slog.e(TAG, "Exception in getting spell checker session: " + e);
bindGroup.removeAll();
@@ -221,7 +234,7 @@
}
final long ident = Binder.clearCallingIdentity();
try {
- startSpellCheckerServiceInnerLocked(info, locale, tsListener, scListener);
+ startSpellCheckerServiceInnerLocked(info, locale, tsListener, scListener, uid);
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -230,7 +243,11 @@
}
private void startSpellCheckerServiceInnerLocked(SpellCheckerInfo info, String locale,
- ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener) {
+ ITextServicesSessionListener tsListener, ISpellCheckerSessionListener scListener,
+ int uid) {
+ if (DBG) {
+ Slog.w(TAG, "Start spell checker session inner locked.");
+ }
final String sciId = info.getId();
final InternalServiceConnection connection = new InternalServiceConnection(
sciId, locale, scListener);
@@ -244,7 +261,7 @@
return;
}
final SpellCheckerBindGroup group = new SpellCheckerBindGroup(
- connection, tsListener, locale, scListener);
+ connection, tsListener, locale, scListener, uid);
mSpellCheckerBindGroups.put(sciId, group);
}
@@ -272,19 +289,39 @@
}
}
- private void setCurrentSpellChecker(SpellCheckerInfo sci) {
+ @Override
+ public void setCurrentSpellChecker(SpellCheckerInfo sci) {
+ synchronized(mSpellCheckerMap) {
+ if (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException(
+ "Requires permission "
+ + android.Manifest.permission.WRITE_SECURE_SETTINGS);
+ }
+ setCurrentSpellCheckerLocked(sci);
+ }
+ }
+
+ private void setCurrentSpellCheckerLocked(SpellCheckerInfo sci) {
if (DBG) {
Slog.w(TAG, "setCurrentSpellChecker: " + sci.getId());
}
- if (sci == null || mSpellCheckerMap.containsKey(sci.getId())) return;
- Settings.Secure.putString(mContext.getContentResolver(),
- Settings.Secure.SPELL_CHECKER_SERVICE, sci == null ? "" : sci.getId());
+ if (sci == null || !mSpellCheckerMap.containsKey(sci.getId())) return;
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ Settings.Secure.putString(mContext.getContentResolver(),
+ Settings.Secure.SPELL_CHECKER_SERVICE, sci == null ? "" : sci.getId());
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
// SpellCheckerBindGroup contains active text service session listeners.
// If there are no listeners anymore, the SpellCheckerBindGroup instance will be removed from
// mSpellCheckerBindGroups
private class SpellCheckerBindGroup {
+ private final String TAG = SpellCheckerBindGroup.class.getSimpleName();
private final InternalServiceConnection mInternalConnection;
private final ArrayList<InternalDeathRecipient> mListeners =
new ArrayList<InternalDeathRecipient>();
@@ -293,10 +330,10 @@
public SpellCheckerBindGroup(InternalServiceConnection connection,
ITextServicesSessionListener listener, String locale,
- ISpellCheckerSessionListener scListener) {
+ ISpellCheckerSessionListener scListener, int uid) {
mInternalConnection = connection;
mConnected = false;
- addListener(listener, locale, scListener);
+ addListener(listener, locale, scListener, uid);
}
public void onServiceConnected(ISpellCheckerService spellChecker) {
@@ -310,7 +347,7 @@
listener.mScLocale, listener.mScListener);
listener.mTsListener.onServiceConnected(session);
} catch (RemoteException e) {
- Slog.e(TAG, "Exception in getting spell checker session: " + e);
+ Slog.e(TAG, "Exception in getting the spell checker session: " + e);
removeAll();
return;
}
@@ -321,7 +358,7 @@
}
public InternalDeathRecipient addListener(ITextServicesSessionListener tsListener,
- String locale, ISpellCheckerSessionListener scListener) {
+ String locale, ISpellCheckerSessionListener scListener, int uid) {
if (DBG) {
Slog.d(TAG, "addListener: " + locale);
}
@@ -336,10 +373,9 @@
}
}
recipient = new InternalDeathRecipient(
- this, tsListener, locale, scListener);
+ this, tsListener, locale, scListener, uid);
scListener.asBinder().linkToDeath(recipient, 0);
- mListeners.add(new InternalDeathRecipient(
- this, tsListener, locale, scListener));
+ mListeners.add(recipient);
} catch(RemoteException e) {
// do nothing
}
@@ -350,7 +386,7 @@
public void removeListener(ISpellCheckerSessionListener listener) {
if (DBG) {
- Slog.d(TAG, "remove listener");
+ Slog.w(TAG, "remove listener: " + listener.hashCode());
}
synchronized(mSpellCheckerMap) {
final int size = mListeners.size();
@@ -359,11 +395,17 @@
for (int i = 0; i < size; ++i) {
final InternalDeathRecipient tempRecipient = mListeners.get(i);
if(tempRecipient.hasSpellCheckerListener(listener)) {
+ if (DBG) {
+ Slog.w(TAG, "found existing listener.");
+ }
removeList.add(tempRecipient);
}
}
final int removeSize = removeList.size();
for (int i = 0; i < removeSize; ++i) {
+ if (DBG) {
+ Slog.w(TAG, "Remove " + removeList.get(i));
+ }
mListeners.remove(removeList.get(i));
}
cleanLocked();
@@ -385,8 +427,10 @@
public void removeAll() {
Slog.e(TAG, "Remove the spell checker bind unexpectedly.");
- mListeners.clear();
- cleanLocked();
+ synchronized(mSpellCheckerMap) {
+ mListeners.clear();
+ cleanLocked();
+ }
}
}
@@ -426,17 +470,19 @@
public final ISpellCheckerSessionListener mScListener;
public final String mScLocale;
private final SpellCheckerBindGroup mGroup;
+ public final int mUid;
public InternalDeathRecipient(SpellCheckerBindGroup group,
ITextServicesSessionListener tsListener, String scLocale,
- ISpellCheckerSessionListener scListener) {
+ ISpellCheckerSessionListener scListener, int uid) {
mTsListener = tsListener;
mScListener = scListener;
mScLocale = scLocale;
mGroup = group;
+ mUid = uid;
}
public boolean hasSpellCheckerListener(ISpellCheckerSessionListener listener) {
- return mScListener.equals(listener);
+ return listener.asBinder().equals(mScListener.asBinder());
}
@Override
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 66f88fc..14c6306 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -53,7 +53,7 @@
import android.app.backup.IBackupManager;
import android.content.ActivityNotFoundException;
import android.content.BroadcastReceiver;
-import android.content.ComponentCallbacks;
+import android.content.ComponentCallbacks2;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
@@ -8067,6 +8067,21 @@
if (needSep) pw.println(" ");
needSep = true;
+ pw.println(" OOM levels:");
+ pw.print(" SYSTEM_ADJ: "); pw.println(SYSTEM_ADJ);
+ pw.print(" CORE_SERVER_ADJ: "); pw.println(CORE_SERVER_ADJ);
+ pw.print(" FOREGROUND_APP_ADJ: "); pw.println(FOREGROUND_APP_ADJ);
+ pw.print(" VISIBLE_APP_ADJ: "); pw.println(VISIBLE_APP_ADJ);
+ pw.print(" PERCEPTIBLE_APP_ADJ: "); pw.println(PERCEPTIBLE_APP_ADJ);
+ pw.print(" HEAVY_WEIGHT_APP_ADJ: "); pw.println(HEAVY_WEIGHT_APP_ADJ);
+ pw.print(" BACKUP_APP_ADJ: "); pw.println(BACKUP_APP_ADJ);
+ pw.print(" SECONDARY_SERVER_ADJ: "); pw.println(SECONDARY_SERVER_ADJ);
+ pw.print(" HOME_APP_ADJ: "); pw.println(HOME_APP_ADJ);
+ pw.print(" HIDDEN_APP_MIN_ADJ: "); pw.println(HIDDEN_APP_MIN_ADJ);
+ pw.print(" EMPTY_APP_ADJ: "); pw.println(EMPTY_APP_ADJ);
+
+ if (needSep) pw.println(" ");
+ needSep = true;
pw.println(" Process OOM control:");
dumpProcessOomList(pw, this, procs, " ",
"Proc", "PERS", true);
@@ -8814,7 +8829,8 @@
pw.print(" ");
pw.print("keeping="); pw.print(r.keeping);
pw.print(" hidden="); pw.print(r.hidden);
- pw.print(" empty="); pw.println(r.empty);
+ pw.print(" empty="); pw.print(r.empty);
+ pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
if (!r.keeping) {
if (r.lastWakeTime != 0) {
@@ -9226,6 +9242,7 @@
app.foregroundServices = false;
app.foregroundActivities = false;
app.hasShownUi = false;
+ app.hasAboveClient = false;
killServicesLocked(app, allowRestart);
@@ -10452,6 +10469,9 @@
activity.connections.add(c);
}
b.client.connections.add(c);
+ if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
+ b.client.hasAboveClient = true;
+ }
clist = mServiceConnections.get(binder);
if (clist == null) {
clist = new ArrayList<ConnectionRecord>();
@@ -10523,6 +10543,9 @@
}
if (b.client != skipApp) {
b.client.connections.remove(c);
+ if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
+ b.client.updateHasAboveClientLocked();
+ }
}
clist = mServiceConnections.get(binder);
if (clist != null) {
@@ -12577,9 +12600,9 @@
// an earlier hidden adjustment that isn't really for us... if
// so, use the new hidden adjustment.
if (!recursed && app.hidden) {
- app.curAdj = hiddenAdj;
+ app.curAdj = app.curRawAdj = hiddenAdj;
}
- return app.curAdj;
+ return app.curRawAdj;
}
if (app.thread == null) {
@@ -12588,28 +12611,47 @@
return (app.curAdj=EMPTY_APP_ADJ);
}
+ app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
+ app.adjSource = null;
+ app.adjTarget = null;
+ app.empty = false;
+ app.hidden = false;
+
+ final int activitiesSize = app.activities.size();
+
if (app.maxAdj <= FOREGROUND_APP_ADJ) {
// The max adjustment doesn't allow this app to be anything
// below foreground, so it is not worth doing work for it.
app.adjType = "fixed";
app.adjSeq = mAdjSeq;
app.curRawAdj = app.maxAdj;
+ app.foregroundActivities = false;
app.keeping = true;
app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
+ // System process can do UI, and when they do we want to have
+ // them trim their memory after the user leaves the UI. To
+ // facilitate this, here we need to determine whether or not it
+ // is currently showing UI.
+ app.systemNoUi = true;
+ if (app == TOP_APP) {
+ app.systemNoUi = false;
+ } else if (activitiesSize > 0) {
+ for (int j = 0; j < activitiesSize; j++) {
+ final ActivityRecord r = app.activities.get(j);
+ if (r.visible) {
+ app.systemNoUi = false;
+ break;
+ }
+ }
+ }
return (app.curAdj=app.maxAdj);
}
final boolean hadForegroundActivities = app.foregroundActivities;
- app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
- app.adjSource = null;
- app.adjTarget = null;
- app.keeping = false;
- app.empty = false;
- app.hidden = false;
app.foregroundActivities = false;
-
- final int activitiesSize = app.activities.size();
+ app.keeping = false;
+ app.systemNoUi = false;
// Determine the importance of the process, starting with most
// important to least, and assign an appropriate OOM adjustment.
@@ -12784,7 +12826,7 @@
// Binding to ourself is not interesting.
continue;
}
- if ((cr.flags&Context.BIND_AUTO_CREATE) != 0) {
+ if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
ProcessRecord client = cr.binding.client;
int clientAdj = adj;
int myHiddenAdj = hiddenAdj;
@@ -12825,15 +12867,32 @@
}
}
if (adj > clientAdj) {
- adj = clientAdj >= VISIBLE_APP_ADJ
- ? clientAdj : VISIBLE_APP_ADJ;
- if (!client.hidden) {
- app.hidden = false;
+ // If this process has recently shown UI, and
+ // the process that is binding to it is less
+ // important than being visible, then we don't
+ // care about the binding as much as we care
+ // about letting this process get into the LRU
+ // list to be killed and restarted if needed for
+ // memory.
+ if (app.hasShownUi && clientAdj > PERCEPTIBLE_APP_ADJ) {
+ adjType = "bound-bg-ui-services";
+ } else {
+ if ((cr.flags&(Context.BIND_ABOVE_CLIENT
+ |Context.BIND_IMPORTANT)) != 0) {
+ adj = clientAdj;
+ } else if (clientAdj >= VISIBLE_APP_ADJ) {
+ adj = clientAdj;
+ } else {
+ adj = VISIBLE_APP_ADJ;
+ }
+ if (!client.hidden) {
+ app.hidden = false;
+ }
+ if (client.keeping) {
+ app.keeping = true;
+ }
+ adjType = "service";
}
- if (client.keeping) {
- app.keeping = true;
- }
- adjType = "service";
}
if (adjType != null) {
app.adjType = adjType;
@@ -12848,21 +12907,22 @@
}
}
}
- ActivityRecord a = cr.activity;
- //if (a != null) {
- // Slog.i(TAG, "Connection to " + a ": state=" + a.state);
- //}
- if (a != null && adj > FOREGROUND_APP_ADJ &&
- (a.state == ActivityState.RESUMED
- || a.state == ActivityState.PAUSING)) {
- adj = FOREGROUND_APP_ADJ;
- schedGroup = Process.THREAD_GROUP_DEFAULT;
- app.hidden = false;
- app.adjType = "service";
- app.adjTypeCode = ActivityManager.RunningAppProcessInfo
- .REASON_SERVICE_IN_USE;
- app.adjSource = a;
- app.adjTarget = s.name;
+ if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
+ ActivityRecord a = cr.activity;
+ if (a != null && adj > FOREGROUND_APP_ADJ &&
+ (a.visible || a.state == ActivityState.RESUMED
+ || a.state == ActivityState.PAUSING)) {
+ adj = FOREGROUND_APP_ADJ;
+ if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
+ schedGroup = Process.THREAD_GROUP_DEFAULT;
+ }
+ app.hidden = false;
+ app.adjType = "service";
+ app.adjTypeCode = ActivityManager.RunningAppProcessInfo
+ .REASON_SERVICE_IN_USE;
+ app.adjSource = a;
+ app.adjTarget = s.name;
+ }
}
}
}
@@ -12906,15 +12966,19 @@
int clientAdj = computeOomAdjLocked(
client, myHiddenAdj, TOP_APP, true);
if (adj > clientAdj) {
- adj = clientAdj > FOREGROUND_APP_ADJ
- ? clientAdj : FOREGROUND_APP_ADJ;
+ if (app.hasShownUi && clientAdj > PERCEPTIBLE_APP_ADJ) {
+ app.adjType = "bg-ui-provider";
+ } else {
+ adj = clientAdj > FOREGROUND_APP_ADJ
+ ? clientAdj : FOREGROUND_APP_ADJ;
+ app.adjType = "provider";
+ }
if (!client.hidden) {
app.hidden = false;
}
if (client.keeping) {
app.keeping = true;
}
- app.adjType = "provider";
app.adjTypeCode = ActivityManager.RunningAppProcessInfo
.REASON_PROVIDER_IN_USE;
app.adjSource = client;
@@ -12955,6 +13019,25 @@
app.keeping = true;
}
+ if (app.hasAboveClient) {
+ // If this process has bound to any services with BIND_ABOVE_CLIENT,
+ // then we need to drop its adjustment to be lower than the service's
+ // in order to honor the request. We want to drop it by one adjustment
+ // level... but there is special meaning applied to various levels so
+ // we will skip some of them.
+ if (adj < FOREGROUND_APP_ADJ) {
+ // System process will not get dropped, ever
+ } else if (adj < VISIBLE_APP_ADJ) {
+ adj = VISIBLE_APP_ADJ;
+ } else if (adj < PERCEPTIBLE_APP_ADJ) {
+ adj = PERCEPTIBLE_APP_ADJ;
+ } else if (adj < HIDDEN_APP_MIN_ADJ) {
+ adj = HIDDEN_APP_MIN_ADJ;
+ } else if (adj < EMPTY_APP_ADJ) {
+ adj++;
+ }
+ }
+
app.curAdj = adj;
app.curSchedGroup = schedGroup;
@@ -12963,7 +13046,7 @@
app.foregroundActivities).sendToTarget();
}
- return adj;
+ return app.curRawAdj;
}
/**
@@ -13204,7 +13287,7 @@
final boolean wasKeeping = app.keeping;
- int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
+ computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
if (app.curRawAdj != app.setRawAdj) {
if (app.curRawAdj > FOREGROUND_APP_ADJ
@@ -13233,14 +13316,14 @@
app.setRawAdj = app.curRawAdj;
}
- if (adj != app.setAdj) {
- if (Process.setOomAdj(app.pid, adj)) {
+ if (app.curAdj != app.setAdj) {
+ if (Process.setOomAdj(app.pid, app.curAdj)) {
if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(
TAG, "Set app " + app.processName +
- " oom adj to " + adj + " because " + app.adjType);
- app.setAdj = adj;
+ " oom adj to " + app.curAdj + " because " + app.adjType);
+ app.setAdj = app.curAdj;
} else {
- Slog.w(TAG, "Failed setting oom adj of " + app + " to " + adj);
+ Slog.w(TAG, "Failed setting oom adj of " + app + " to " + app.curAdj);
}
}
if (app.setSchedGroup != app.curSchedGroup) {
@@ -13377,7 +13460,7 @@
final int N = mLruProcesses.size();
factor = numBg/3;
step = 0;
- int curLevel = ComponentCallbacks.TRIM_MEMORY_COMPLETE;
+ int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
for (i=0; i<N; i++) {
ProcessRecord app = mLruProcesses.get(i);
if (app.curAdj >= HIDDEN_APP_MIN_ADJ && !app.killedBackground) {
@@ -13386,7 +13469,7 @@
app.thread.scheduleTrimMemory(curLevel);
} catch (RemoteException e) {
}
- if (curLevel >= ComponentCallbacks.TRIM_MEMORY_COMPLETE) {
+ if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE) {
// For these apps we will also finish their activities
// to help them free memory.
mMainStack.destroyActivitiesLocked(app, false);
@@ -13396,23 +13479,36 @@
step++;
if (step >= factor) {
switch (curLevel) {
- case ComponentCallbacks.TRIM_MEMORY_COMPLETE:
- curLevel = ComponentCallbacks.TRIM_MEMORY_MODERATE;
+ case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
+ curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
break;
- case ComponentCallbacks.TRIM_MEMORY_MODERATE:
- curLevel = ComponentCallbacks.TRIM_MEMORY_BACKGROUND;
+ case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
+ curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
break;
}
}
} else if (app.curAdj == HEAVY_WEIGHT_APP_ADJ) {
- if (app.trimMemoryLevel < ComponentCallbacks.TRIM_MEMORY_BACKGROUND
+ if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
&& app.thread != null) {
try {
- app.thread.scheduleTrimMemory(ComponentCallbacks.TRIM_MEMORY_BACKGROUND);
+ app.thread.scheduleTrimMemory(
+ ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
} catch (RemoteException e) {
}
}
- app.trimMemoryLevel = ComponentCallbacks.TRIM_MEMORY_BACKGROUND;
+ app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
+ } else if ((app.curAdj > VISIBLE_APP_ADJ || app.systemNoUi)
+ && app.pendingUiClean) {
+ if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
+ && app.thread != null) {
+ try {
+ app.thread.scheduleTrimMemory(
+ ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+ } catch (RemoteException e) {
+ }
+ }
+ app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
+ app.pendingUiClean = false;
} else {
app.trimMemoryLevel = 0;
}
@@ -13421,7 +13517,21 @@
final int N = mLruProcesses.size();
for (i=0; i<N; i++) {
ProcessRecord app = mLruProcesses.get(i);
- app.trimMemoryLevel = 0;
+ if ((app.curAdj > VISIBLE_APP_ADJ || app.systemNoUi)
+ && app.pendingUiClean) {
+ if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
+ && app.thread != null) {
+ try {
+ app.thread.scheduleTrimMemory(
+ ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
+ } catch (RemoteException e) {
+ }
+ }
+ app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
+ app.pendingUiClean = false;
+ } else {
+ app.trimMemoryLevel = 0;
+ }
}
}
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index cc58eaf..33b21ab 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -560,6 +560,7 @@
showAskCompatModeDialogLocked(r);
r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
app.hasShownUi = true;
+ app.pendingUiClean = true;
app.thread.scheduleLaunchActivity(new Intent(r.intent), r,
System.identityHashCode(r),
r.info, r.compat, r.icicle, results, newIntents, !andResume,
diff --git a/services/java/com/android/server/am/AppBindRecord.java b/services/java/com/android/server/am/AppBindRecord.java
index 9c57360..f1c54fa 100644
--- a/services/java/com/android/server/am/AppBindRecord.java
+++ b/services/java/com/android/server/am/AppBindRecord.java
@@ -26,7 +26,7 @@
class AppBindRecord {
final ServiceRecord service; // The running service.
final IntentBindRecord intent; // The intent we are bound to.
- final ProcessRecord client; // Who has started/bound the service.
+ final ProcessRecord client; // Who has started/bound the service.
final HashSet<ConnectionRecord> connections = new HashSet<ConnectionRecord>();
// All ConnectionRecord for this client.
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 5b59363..a896ce4 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -23,6 +23,7 @@
import android.app.IApplicationThread;
import android.app.IInstrumentationWatcher;
import android.content.ComponentName;
+import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.res.CompatibilityInfo;
import android.os.Bundle;
@@ -66,7 +67,10 @@
boolean setIsForeground; // Running foreground UI when last set?
boolean foregroundServices; // Running any services that are foreground?
boolean foregroundActivities; // Running any activities that are foreground?
+ boolean systemNoUi; // This is a system process, but not currently showing UI.
boolean hasShownUi; // Has UI been shown in this process since it was started?
+ boolean pendingUiClean; // Want to clean up resources from showing UI?
+ boolean hasAboveClient; // Bound using BIND_ABOVE_CLIENT, so want to be lower
boolean bad; // True if disabled in the bad process list
boolean killedBackground; // True when proc has been killed due to too many bg
String waitingToKill; // Process is waiting to be killed when in the bg; reason
@@ -185,8 +189,11 @@
pw.print(" set="); pw.println(setAdj);
pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
pw.print(" setSchedGroup="); pw.print(setSchedGroup);
+ pw.print(" systemNoUi="); pw.print(systemNoUi);
pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
- pw.print(" hasShownUi="); pw.println(hasShownUi);
+ pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
+ pw.print(" pendingUiClean="); pw.print(pendingUiClean);
+ pw.print(" hasAboveClient="); pw.println(hasAboveClient);
pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
pw.print(" foregroundServices="); pw.print(foregroundServices);
pw.print(" forcingToForeground="); pw.println(forcingToForeground);
@@ -307,6 +314,18 @@
deathRecipient = null;
}
+ void updateHasAboveClientLocked() {
+ hasAboveClient = false;
+ if (connections.size() > 0) {
+ for (ConnectionRecord cr : connections) {
+ if ((cr.flags&Context.BIND_ABOVE_CLIENT) != 0) {
+ hasAboveClient = true;
+ break;
+ }
+ }
+ }
+ }
+
public String toShortString() {
if (shortStringName != null) {
return shortStringName;
diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
index e75a079..da5f488 100644
--- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
@@ -48,6 +48,8 @@
StatusBarManager mStatusBarManager;
NotificationManager mNotificationManager;
Handler mHandler = new Handler();
+ int mUiVisibility = 0;
+ View mListView;
View.OnSystemUiVisibilityChangeListener mOnSystemUiVisibilityChangeListener
= new View.OnSystemUiVisibilityChangeListener() {
@@ -69,32 +71,52 @@
return mTests;
}
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ mListView = findViewById(android.R.id.list);
+ mListView.setOnSystemUiVisibilityChangeListener(mOnSystemUiVisibilityChangeListener);
+ }
+
private Test[] mTests = new Test[] {
+ new Test("toggle LOW_PROFILE (lights out)") {
+ public void run() {
+ if (0 != (mUiVisibility & View.SYSTEM_UI_FLAG_LOW_PROFILE)) {
+ mUiVisibility &= ~View.SYSTEM_UI_FLAG_LOW_PROFILE;
+ } else {
+ mUiVisibility |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
+ }
+ mListView.setSystemUiVisibility(mUiVisibility);
+ }
+ },
+ new Test("toggle HIDE_NAVIGATION") {
+ public void run() {
+ if (0 != (mUiVisibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION)) {
+ mUiVisibility &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ } else {
+ mUiVisibility |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+ }
+ mListView.setSystemUiVisibility(mUiVisibility);
+
+ }
+ },
+ new Test("clear SYSTEM_UI_FLAGs") {
+ public void run() {
+ mUiVisibility = 0;
+ mListView.setSystemUiVisibility(mUiVisibility);
+ }
+ },
+// new Test("no setSystemUiVisibility") {
+// public void run() {
+// View v = findViewById(android.R.id.list);
+// v.setOnSystemUiVisibilityChangeListener(null);
+// v.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
+// }
+// },
new Test("DISABLE_NAVIGATION") {
public void run() {
- View v = findViewById(android.R.id.list);
- v.setSystemUiVisibility(View.STATUS_BAR_DISABLE_NAVIGATION);
- }
- },
- new Test("STATUS_BAR_HIDDEN") {
- public void run() {
- View v = findViewById(android.R.id.list);
- v.setOnSystemUiVisibilityChangeListener(mOnSystemUiVisibilityChangeListener);
- v.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
- }
- },
- new Test("STATUS_BAR_VISIBLE") {
- public void run() {
- View v = findViewById(android.R.id.list);
- v.setOnSystemUiVisibilityChangeListener(mOnSystemUiVisibilityChangeListener);
- v.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
- }
- },
- new Test("no setSystemUiVisibility") {
- public void run() {
- View v = findViewById(android.R.id.list);
- v.setOnSystemUiVisibilityChangeListener(null);
- v.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
+ mListView.setSystemUiVisibility(View.STATUS_BAR_DISABLE_NAVIGATION);
}
},
new Test("Double Remove") {