summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/app/Activity.java19
-rw-r--r--core/java/android/app/ActivityManagerNative.java22
-rw-r--r--core/java/android/app/IActivityManager.java3
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java28
-rw-r--r--services/java/com/android/server/am/ActivityRecord.java17
-rw-r--r--services/java/com/android/server/am/ActivityStack.java24
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java8
8 files changed, 111 insertions, 11 deletions
diff --git a/api/current.txt b/api/current.txt
index 92aa494..ac3144d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2697,6 +2697,7 @@ package android.app {
method public void addContentView(android.view.View, android.view.ViewGroup.LayoutParams);
method public void closeContextMenu();
method public void closeOptionsMenu();
+ method public void convertToOpaque();
method public android.app.PendingIntent createPendingResult(int, android.content.Intent, int);
method public final deprecated void dismissDialog(int);
method public boolean dispatchGenericMotionEvent(android.view.MotionEvent);
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 7f2f744..e87d805 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -4862,6 +4862,25 @@ public class Activity extends ContextThemeWrapper
}
/**
+ * Convert a translucent themed Activity {@link android.R.attr#windowIsTranslucent} to a
+ * fullscreen opaque Activity.
+ *
+ * Call this whenever the background of a translucent Activity has changed to become opaque.
+ * Doing so will allow the previously visible Activity behind this one to be stopped. Stopped
+ * apps consume no CPU cycles and are eligible for removal when reclaiming memory.
+ *
+ * This call has no effect on non-translucent activities or on activities with the
+ * {@link android.R.attr#windowIsFloating} attribute.
+ */
+ public void convertToOpaque() {
+ try {
+ ActivityManagerNative.getDefault().convertToOpaque(mToken);
+ } catch (RemoteException e) {
+ // pass
+ }
+ }
+
+ /**
* Adjust the current immersive mode setting.
*
* Note that changing this value will have no effect on the activity's
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 1573398..b966d6d 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1499,6 +1499,14 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
return true;
}
+ case CONVERT_TO_OPAQUE_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ IBinder token = data.readStrongBinder();
+ convertToOpaque(token);
+ reply.writeNoException();
+ return true;
+ }
+
case SET_IMMERSIVE_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder token = data.readStrongBinder();
@@ -3823,7 +3831,19 @@ class ActivityManagerProxy implements IActivityManager
data.recycle();
reply.recycle();
}
-
+
+ public void convertToOpaque(IBinder token)
+ throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeStrongBinder(token);
+ mRemote.transact(CONVERT_TO_OPAQUE_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
public void setImmersive(IBinder token, boolean immersive)
throws RemoteException {
Parcel data = Parcel.obtain();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index c8791a4..39f4cfa 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -301,6 +301,8 @@ public interface IActivityManager extends IInterface {
public void finishHeavyWeightApp() throws RemoteException;
+ public void convertToOpaque(IBinder token) throws RemoteException;
+
public void setImmersive(IBinder token, boolean immersive) throws RemoteException;
public boolean isImmersive(IBinder token) throws RemoteException;
public boolean isTopActivityImmersive() throws RemoteException;
@@ -666,4 +668,5 @@ public interface IActivityManager extends IInterface {
int GET_STACK_BOXES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+170;
int SET_FOCUSED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+171;
int GET_STACK_BOX_INFO_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+172;
+ int CONVERT_TO_OPAQUE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+173;
}
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index e37eec6..ad6ae43 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -7910,12 +7910,33 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ @Override
public void unregisterProcessObserver(IProcessObserver observer) {
synchronized (this) {
mProcessObservers.unregister(observer);
}
}
+ @Override
+ public void convertToOpaque(IBinder token) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ synchronized (this) {
+ final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ return;
+ }
+ if (r.convertToOpaque()) {
+ mWindowManager.setAppFullscreen(token);
+ mStackSupervisor.ensureActivitiesVisibleLocked(null, 0);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ @Override
public void setImmersive(IBinder token, boolean immersive) {
synchronized(this) {
final ActivityRecord r = ActivityRecord.isInStackLocked(token);
@@ -7934,6 +7955,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
+ @Override
public boolean isImmersive(IBinder token) {
synchronized (this) {
ActivityRecord r = ActivityRecord.isInStackLocked(token);
@@ -8006,7 +8028,7 @@ public final class ActivityManagerService extends ActivityManagerNative
String reason = (pReason == null) ? "Unknown" : pReason;
// XXX Note: don't acquire main activity lock here, because the window
// manager calls in with its locks held.
-
+
boolean killed = false;
synchronized (mPidsSelfLocked) {
int[] types = new int[pids.length];
@@ -8021,7 +8043,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
}
-
+
// If the worst oom_adj is somewhere in the cached proc LRU range,
// then constrain it so we will kill all cached procs.
if (worstType < ProcessList.CACHED_APP_MAX_ADJ
@@ -8188,7 +8210,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// no need to synchronize(this) just to read & return the value
return mSystemReady;
}
-
+
private static File getCalledPreBootReceiversFile() {
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 561dd0f..f730e07 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -71,7 +71,7 @@ final class ActivityRecord {
final String processName; // process where this component wants to run
final String taskAffinity; // as per ActivityInfo.taskAffinity
final boolean stateNotNeeded; // As per ActivityInfo.flags
- final boolean fullscreen; // covers the full screen?
+ boolean fullscreen; // covers the full screen?
final boolean noDisplay; // activity is not displayed?
final boolean componentSpecified; // did caller specifiy an explicit component?
@@ -503,6 +503,21 @@ final class ActivityRecord {
}
}
+ boolean convertToOpaque() {
+ if (fullscreen) {
+ return false;
+ }
+
+ AttributeCache.Entry ent = AttributeCache.instance().get(packageName,
+ realTheme, com.android.internal.R.styleable.Window);
+ if (ent != null && !ent.array.getBoolean(
+ com.android.internal.R.styleable.Window_windowIsFloating, false)) {
+ fullscreen = true;
+ ++task.numFullscreen;
+ }
+ return fullscreen;
+ }
+
void putInHistory() {
if (!inHistory) {
inHistory = true;
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index a9ab53d..8e8bb55 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1088,11 +1088,25 @@ final class ActivityStack {
r.visible = false;
try {
mWindowManager.setAppVisibility(r.appToken, false);
- if ((r.state == ActivityState.STOPPING
- || r.state == ActivityState.STOPPED)
- && r.app != null && r.app.thread != null) {
- if (DEBUG_VISBILITY) Slog.v(TAG, "Scheduling invisibility: " + r);
- r.app.thread.scheduleWindowVisibility(r.appToken, false);
+ switch (r.state) {
+ case STOPPING:
+ case STOPPED:
+ if (r.app != null && r.app.thread != null) {
+ if (DEBUG_VISBILITY) Slog.v(
+ TAG, "Scheduling invisibility: " + r);
+ r.app.thread.scheduleWindowVisibility(r.appToken, false);
+ }
+ break;
+
+ case INITIALIZING:
+ case RESUMED:
+ case PAUSING:
+ case PAUSED:
+ stopActivityLocked(r);
+ break;
+
+ default:
+ break;
}
} catch (Exception e) {
// Just skip on any failure; we'll make it
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 0babeea..ee2ef37 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -98,7 +98,6 @@ import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.Choreographer;
import android.view.Display;
-import android.view.DisplayAdjustments;
import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.IApplicationToken;
@@ -4118,6 +4117,13 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
+ public void setAppFullscreen(IBinder token) {
+ AppWindowToken atoken = findAppWindowToken(token);
+ if (atoken != null) {
+ atoken.appFullscreen = true;
+ }
+ }
+
boolean setTokenVisibilityLocked(AppWindowToken wtoken, WindowManager.LayoutParams lp,
boolean visible, int transit, boolean performLayout) {
boolean delayed = false;