summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2017-02-18 00:11:37 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2017-02-18 00:11:41 +0000
commit4b441535c32252d12663f0fa2d7178472fe82d4d (patch)
treedfd13a21af2b66dffb9ebb9faa92d875649067bf
parent18c76bb197327859fc88ea9e2ead52495033e27a (diff)
parent387e4c61338ddf7aee89d10c8aac329e9562b831 (diff)
Merge changes Ie28325b6,I4e406a94
* changes: Display on-going notification for apps using alert windows. Set importance for processes displaying app-overlays based on visibility
-rw-r--r--core/res/AndroidManifest.xml1
-rw-r--r--core/res/res/drawable-nodpi/alert_window_layer.xml24
-rw-r--r--core/res/res/values/strings.xml15
-rw-r--r--core/res/res/values/symbols.xml8
-rw-r--r--services/core/java/com/android/server/wm/AlertWindowNotification.java144
-rw-r--r--services/core/java/com/android/server/wm/Session.java91
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java55
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java4
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java48
9 files changed, 334 insertions, 56 deletions
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 3ca22086acc0..ff70a69d94db 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -520,6 +520,7 @@
<!-- TODO: temporary broadcast used by AutoFillManagerServiceImpl; will be removed -->
<protected-broadcast android:name="com.android.internal.autofill.action.REQUEST_AUTOFILL" />
<protected-broadcast android:name="android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED" />
+ <protected-broadcast android:name="com.android.server.wm.ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION" />
<!-- ====================================================================== -->
<!-- RUNTIME PERMISSIONS -->
diff --git a/core/res/res/drawable-nodpi/alert_window_layer.xml b/core/res/res/drawable-nodpi/alert_window_layer.xml
new file mode 100644
index 000000000000..f9b38c8e57c4
--- /dev/null
+++ b/core/res/res/drawable-nodpi/alert_window_layer.xml
@@ -0,0 +1,24 @@
+<!--
+Copyright (C) 2017 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0">
+<path
+ android:fillColor="#FF000000"
+ android:pathData="M11.99,18.54l-7.37,-5.73L3,14.07l9,7 9,-7 -1.63,-1.27 -7.38,5.74zM12,16l7.36,-5.73L21,9l-9,-7 -9,7 1.63,1.27L12,16z"/>
+</vector>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 8faa76cda808..7069d16c0a32 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3116,6 +3116,21 @@
<string name="fast_scroll_alphabet">\u0020ABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
<string name="fast_scroll_numeric_alphabet">\u00200123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ</string>
+ <!-- Alert windows notification strings -->
+ <skip />
+ <!-- Name of notification channel the system post notification to inform the use about apps
+ that are drawing ui on-top of other apps (alert-windows) [CHAR LIMIT=NONE] -->
+ <string name="alert_windows_notification_channel_name"><xliff:g id="name" example="Google Maps">%s</xliff:g> draw over other apps</string>
+ <!-- Notification title when an application is displaying ui on-top of other apps
+ [CHAR LIMIT=30] -->
+ <string name="alert_windows_notification_title"><xliff:g id="name" example="Google Maps">%s</xliff:g> app displaying on top.</string>
+ <!-- Notification body when an application is displaying ui on-top of other apps
+ [CHAR LIMIT=NONE] -->
+ <string name="alert_windows_notification_message">Parts of this app may remain visible at all times. If this feature isn\'t working correctly, turn it off.</string>
+ <!-- Notification action to turn-off app displaying on-top of other apps. [CHAR LIMIT=20] -->
+ <string name="alert_windows_notification_turn_off_action">TURN OFF</string>
+
+
<!-- External media notification strings -->
<skip />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 0d63a1e48420..a4605c3fa160 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2867,4 +2867,12 @@
<!-- resolver activity -->
<java-symbol type="drawable" name="resolver_icon_placeholder" />
+
+ <!-- Alert windows notification -->
+ <java-symbol type="string" name="alert_windows_notification_channel_name" />
+ <java-symbol type="string" name="alert_windows_notification_title" />
+ <java-symbol type="string" name="alert_windows_notification_message" />
+ <java-symbol type="string" name="alert_windows_notification_turn_off_action" />
+ <java-symbol type="drawable" name="alert_window_layer" />
+
</resources>
diff --git a/services/core/java/com/android/server/wm/AlertWindowNotification.java b/services/core/java/com/android/server/wm/AlertWindowNotification.java
new file mode 100644
index 000000000000..0d282ef3f8d6
--- /dev/null
+++ b/services/core/java/com/android/server/wm/AlertWindowNotification.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2017 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 com.android.server.wm;
+
+import static android.app.Notification.VISIBILITY_PRIVATE;
+import static android.app.NotificationManager.IMPORTANCE_MIN;
+import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
+import static android.content.Context.NOTIFICATION_SERVICE;
+import static android.content.Intent.EXTRA_PACKAGE_NAME;
+import static android.content.Intent.EXTRA_UID;
+import static com.android.server.wm.WindowManagerService.ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION;
+
+import android.app.Notification;
+import android.app.NotificationChannel;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import com.android.internal.R;
+
+/** Displays an ongoing notification for a process displaying an alert window */
+class AlertWindowNotification {
+ private static final String CHANNEL_PREFIX = "com.android.server.wm.AlertWindowNotification - ";
+ private static final int NOTIFICATION_ID = 0;
+
+ private static int sNextRequestCode = 0;
+ private final int mRequestCode;
+ private final WindowManagerService mService;
+ private String mNotificationTag;
+ private final NotificationManager mNotificationManager;
+ private final String mPackageName;
+ private final int mUid;
+ private boolean mCancelled;
+
+ AlertWindowNotification(WindowManagerService service, String packageName, int uid) {
+ mService = service;
+ mPackageName = packageName;
+ mUid = uid;
+ mNotificationManager =
+ (NotificationManager) mService.mContext.getSystemService(NOTIFICATION_SERVICE);
+ mNotificationTag = CHANNEL_PREFIX + mPackageName;
+ mRequestCode = sNextRequestCode++;
+
+ // We can't create/post the notification while the window manager lock is held since it will
+ // end up calling into activity manager. So, we post a message to do it later.
+ mService.mH.post(this::postNotification);
+ }
+
+ /** Cancels the notification */
+ void cancel() {
+ mNotificationManager.cancel(mNotificationTag, NOTIFICATION_ID);
+ mCancelled = true;
+ }
+
+ /** Don't call with the window manager lock held! */
+ private void postNotification() {
+ final Context context = mService.mContext;
+ final PackageManager pm = context.getPackageManager();
+ final ApplicationInfo aInfo = getApplicationInfo(pm, mPackageName);
+ final String appName = (aInfo != null)
+ ? pm.getApplicationLabel(aInfo).toString() : mPackageName;
+
+ createNotificationChannelIfNeeded(context, appName);
+
+ final String message = context.getString(R.string.alert_windows_notification_message);
+ final Notification.Builder builder = new Notification.Builder(context, mNotificationTag)
+ .setOngoing(true)
+ .setContentTitle(
+ context.getString(R.string.alert_windows_notification_title, appName))
+ .setContentText(message)
+ .setSmallIcon(R.drawable.alert_window_layer)
+ .setColor(context.getColor(R.color.system_notification_accent_color))
+ .setStyle(new Notification.BigTextStyle().bigText(message))
+ .setLocalOnly(true)
+ .addAction(getTurnOffAction(context, mPackageName, mUid));
+
+ if (aInfo != null) {
+ final Bitmap bitmap = ((BitmapDrawable) pm.getApplicationIcon(aInfo)).getBitmap();
+ builder.setLargeIcon(bitmap);
+ }
+
+ synchronized (mService.mWindowMap) {
+ if (mCancelled) {
+ // Notification was cancelled, so nothing more to do...
+ return;
+ }
+ mNotificationManager.notify(mNotificationTag, NOTIFICATION_ID, builder.build());
+ }
+ }
+
+ private Notification.Action getTurnOffAction(Context context, String packageName, int uid) {
+ final Intent intent = new Intent(ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION);
+ intent.putExtra(EXTRA_PACKAGE_NAME, packageName);
+ intent.putExtra(EXTRA_UID, uid);
+ // Calls into activity manager...
+ final PendingIntent pendingIntent = PendingIntent.getBroadcast(context, mRequestCode,
+ intent, FLAG_CANCEL_CURRENT);
+ return new Notification.Action.Builder(R.drawable.alert_window_layer,
+ context.getString(R.string.alert_windows_notification_turn_off_action),
+ pendingIntent).build();
+
+ }
+
+ private void createNotificationChannelIfNeeded(Context context, String appName) {
+ if (mNotificationManager.getNotificationChannel(mNotificationTag) != null) {
+ return;
+ }
+ final String nameChannel =
+ context.getString(R.string.alert_windows_notification_channel_name, appName);
+ final NotificationChannel channel =
+ new NotificationChannel(mNotificationTag, nameChannel, IMPORTANCE_MIN);
+ channel.enableLights(false);
+ channel.enableVibration(false);
+ mNotificationManager.createNotificationChannel(channel);
+ }
+
+
+ private ApplicationInfo getApplicationInfo(PackageManager pm, String packageName) {
+ try {
+ return pm.getApplicationInfo(packageName, 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ return null;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 782f9f2f6611..5355f3159c86 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -16,7 +16,10 @@
package com.android.server.wm;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.isSystemAlertWindowType;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_DRAG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_TASK_POSITIONING;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
@@ -54,6 +57,8 @@ import com.android.internal.view.IInputMethodManager;
import com.android.server.wm.WindowManagerService.H;
import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Set;
/**
* This class represents an active client session. There is generally one
@@ -70,9 +75,15 @@ public class Session extends IWindowSession.Stub
private final String mStringName;
SurfaceSession mSurfaceSession;
private int mNumWindow = 0;
- private int mNumOverlayWindow = 0;
+ // Set of visible application overlay window surfaces connected to this session.
+ private final Set<WindowSurfaceController> mAppOverlaySurfaces = new HashSet<>();
+ // Set of visible alert window surfaces connected to this session.
+ private final Set<WindowSurfaceController> mAlertWindowSurfaces = new HashSet<>();
+ final boolean mCanAddInternalSystemWindow;
+ private AlertWindowNotification mAlertWindowNotification;
private boolean mClientDead = false;
private float mLastReportedAnimatorScale;
+ private String mPackageName;
public Session(WindowManagerService service, IWindowSessionCallback callback,
IInputMethodClient client, IInputContext inputContext) {
@@ -82,6 +93,8 @@ public class Session extends IWindowSession.Stub
mUid = Binder.getCallingUid();
mPid = Binder.getCallingPid();
mLastReportedAnimatorScale = service.getCurrentAnimatorScale();
+ mCanAddInternalSystemWindow = service.mContext.checkCallingPermission(
+ INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
StringBuilder sb = new StringBuilder();
sb.append("Session{");
sb.append(Integer.toHexString(System.identityHashCode(this)));
@@ -544,7 +557,8 @@ public class Session extends IWindowSession.Stub
}
}
- void windowAddedLocked(int type) {
+ void windowAddedLocked(String packageName) {
+ mPackageName = packageName;
if (mSurfaceSession == null) {
if (WindowManagerService.localLOGV) Slog.v(
TAG_WM, "First window added to " + this + ", creating SurfaceSession");
@@ -557,24 +571,57 @@ public class Session extends IWindowSession.Stub
}
}
mNumWindow++;
- if (type == TYPE_APPLICATION_OVERLAY) {
- mNumOverlayWindow++;
- setHasOverlayUi(true);
- }
}
- void windowRemovedLocked(int type) {
+ void windowRemovedLocked() {
mNumWindow--;
- if (type == TYPE_APPLICATION_OVERLAY) {
- mNumOverlayWindow--;
- if (mNumOverlayWindow == 0) {
- setHasOverlayUi(false);
- } else if (mNumOverlayWindow < 0) {
- throw new IllegalStateException("mNumOverlayWindow=" + mNumOverlayWindow
- + " less than 0 for session=" + this);
+ killSessionLocked();
+ }
+
+
+ void onWindowSurfaceVisibilityChanged(WindowSurfaceController surfaceController,
+ boolean visible, int type) {
+
+ if (!isSystemAlertWindowType(type)) {
+ return;
+ }
+
+ boolean changed;
+
+ if (!mCanAddInternalSystemWindow) {
+ // We want to track non-system signature apps adding alert windows so we can post an
+ // on-going notification for the user to control their visibility.
+ if (visible) {
+ changed = mAlertWindowSurfaces.add(surfaceController);
+ } else {
+ changed = mAlertWindowSurfaces.remove(surfaceController);
+ }
+
+ if (changed) {
+ if (mAlertWindowSurfaces.isEmpty()) {
+ cancelAlertWindowNotification();
+ } else if (mAlertWindowNotification == null){
+ mAlertWindowNotification = new AlertWindowNotification(
+ mService, mPackageName, mUid);
+ }
}
}
- killSessionLocked();
+
+ if (type != TYPE_APPLICATION_OVERLAY) {
+ return;
+ }
+
+ if (visible) {
+ changed = mAppOverlaySurfaces.add(surfaceController);
+ } else {
+ changed = mAppOverlaySurfaces.remove(surfaceController);
+ }
+
+ if (changed) {
+ // Notify activity manager of changes to app overlay windows so it can adjust the
+ // importance score for the process.
+ setHasOverlayUi(!mAppOverlaySurfaces.isEmpty());
+ }
}
private void killSessionLocked() {
@@ -597,16 +644,28 @@ public class Session extends IWindowSession.Stub
+ " in session " + this + ": " + e.toString());
}
mSurfaceSession = null;
+ mAlertWindowSurfaces.clear();
+ mAppOverlaySurfaces.clear();
setHasOverlayUi(false);
+ cancelAlertWindowNotification();
}
private void setHasOverlayUi(boolean hasOverlayUi) {
mService.mH.obtainMessage(H.SET_HAS_OVERLAY_UI, mPid, hasOverlayUi ? 1 : 0).sendToTarget();
}
+ private void cancelAlertWindowNotification() {
+ if (mAlertWindowNotification == null) {
+ return;
+ }
+ mAlertWindowNotification.cancel();
+ mAlertWindowNotification = null;
+ }
+
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("mNumWindow="); pw.print(mNumWindow);
- pw.print(" mNumOverlayWindow="); pw.print(mNumOverlayWindow);
+ pw.print(" mAppOverlaySurfaces="); pw.print(mAppOverlaySurfaces);
+ pw.print(" mAlertWindowSurfaces="); pw.print(mAlertWindowSurfaces);
pw.print(" mClientDead="); pw.print(mClientDead);
pw.print(" mSurfaceSession="); pw.println(mSurfaceSession);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 5653113e2cbd..02c52a7bf21c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -21,8 +21,13 @@ import static android.Manifest.permission.MANAGE_APP_TOKENS;
import static android.Manifest.permission.REGISTER_WINDOW_MANAGER_LISTENERS;
import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
+import static android.app.AppOpsManager.MODE_IGNORED;
+import static android.app.AppOpsManager.OP_SYSTEM_ALERT_WINDOW;
import static android.app.StatusBarManager.DISABLE_MASK;
+import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
import static android.content.Intent.ACTION_USER_REMOVED;
+import static android.content.Intent.EXTRA_PACKAGE_NAME;
+import static android.content.Intent.EXTRA_UID;
import static android.content.Intent.EXTRA_USER_HANDLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -66,6 +71,7 @@ import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_END;
import static com.android.server.wm.AppWindowAnimator.PROLONG_ANIMATION_AT_START;
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_FREEFORM;
+import static com.android.server.wm.KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ANIM;
@@ -343,20 +349,34 @@ public class WindowManagerService extends IWindowManager.Stub
final private KeyguardDisableHandler mKeyguardDisableHandler;
- final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ static final String ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION =
+ "com.android.server.wm.ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION";
+
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- final String action = intent.getAction();
- if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
- mKeyguardDisableHandler.sendEmptyMessage(
- KeyguardDisableHandler.KEYGUARD_POLICY_CHANGED);
- } else if (ACTION_USER_REMOVED.equals(action)) {
- final int userId = intent.getIntExtra(EXTRA_USER_HANDLE, USER_NULL);
- if (userId != USER_NULL) {
- synchronized (mWindowMap) {
- mScreenCaptureDisabled.remove(userId);
+ switch (intent.getAction()) {
+ case ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED:
+ mKeyguardDisableHandler.sendEmptyMessage(KEYGUARD_POLICY_CHANGED);
+ break;
+ case ACTION_USER_REMOVED:
+ final int userId = intent.getIntExtra(EXTRA_USER_HANDLE, USER_NULL);
+ if (userId != USER_NULL) {
+ synchronized (mWindowMap) {
+ mScreenCaptureDisabled.remove(userId);
+ }
}
- }
+ break;
+ case ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION:
+ final String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);
+ final int uid = intent.getIntExtra(EXTRA_UID, -1);
+ if (packageName != null && uid != -1) {
+ synchronized (mWindowMap) {
+ // Revoke permission.
+ mAppOps.setMode(OP_SYSTEM_ALERT_WINDOW, uid, packageName, MODE_IGNORED);
+ }
+ }
+ break;
}
}
};
@@ -1018,7 +1038,7 @@ public class WindowManagerService extends IWindowManager.Stub
updateAppOpsState();
}
};
- mAppOps.startWatchingMode(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, null, opListener);
+ mAppOps.startWatchingMode(OP_SYSTEM_ALERT_WINDOW, null, opListener);
mAppOps.startWatchingMode(AppOpsManager.OP_TOAST_WINDOW, null, opListener);
// Get persisted window scale setting
@@ -1034,9 +1054,10 @@ public class WindowManagerService extends IWindowManager.Stub
IntentFilter filter = new IntentFilter();
// Track changes to DevicePolicyManager state so we can enable/disable keyguard.
- filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
+ filter.addAction(ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
// Listen to user removal broadcasts so that we can remove the user-specific data.
filter.addAction(Intent.ACTION_USER_REMOVED);
+ filter.addAction(ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION);
mContext.registerReceiver(mBroadcastReceiver, filter);
mSettingsObserver = new SettingsObserver();
@@ -1111,8 +1132,6 @@ public class WindowManagerService extends IWindowManager.Stub
long origId;
final int callingUid = Binder.getCallingUid();
final int type = attrs.type;
- final boolean ownerCanAddInternalSystemWindow =
- mContext.checkCallingPermission(INTERNAL_SYSTEM_WINDOW) == PERMISSION_GRANTED;
synchronized(mWindowMap) {
if (!mDisplayReady) {
@@ -1215,7 +1234,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
token = new WindowToken(this, attrs.token, type, false, displayContent,
- ownerCanAddInternalSystemWindow);
+ session.mCanAddInternalSystemWindow);
} else if (rootType >= FIRST_APPLICATION_WINDOW && rootType <= LAST_APPLICATION_WINDOW) {
atoken = token.asAppWindowToken();
if (atoken == null) {
@@ -1286,12 +1305,12 @@ public class WindowManagerService extends IWindowManager.Stub
// instead make a new token for it (as if null had been passed in for the token).
attrs.token = null;
token = new WindowToken(this, null, type, false, displayContent,
- ownerCanAddInternalSystemWindow);
+ session.mCanAddInternalSystemWindow);
}
final WindowState win = new WindowState(this, session, client, token, parentWindow,
appOp[0], seq, attrs, viewVisibility, session.mUid,
- ownerCanAddInternalSystemWindow);
+ session.mCanAddInternalSystemWindow);
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
// continue.
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 7de6856a1213..fe7dc5a95d53 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -665,7 +665,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
void attach() {
if (localLOGV) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
- mSession.windowAddedLocked(mAttrs.type);
+ mSession.windowAddedLocked(mAttrs.packageName);
}
@Override
@@ -1738,7 +1738,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mWinAnimator.destroyDeferredSurfaceLocked();
mWinAnimator.destroySurfaceLocked();
- mSession.windowRemovedLocked(mAttrs.type);
+ mSession.windowRemovedLocked();
try {
mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
} catch (RuntimeException e) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 1096ede96316..f8e74284fafd 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -52,6 +52,7 @@ class WindowSurfaceController {
private SurfaceControl mSurfaceControl;
+ // Should only be set from within setShown().
private boolean mSurfaceShown = false;
private float mSurfaceX = 0;
private float mSurfaceY = 0;
@@ -79,6 +80,9 @@ class WindowSurfaceController {
private final WindowManagerService mService;
+ private final int mWindowType;
+ private final Session mWindowSession;
+
public WindowSurfaceController(SurfaceSession s, String name, int w, int h, int format,
int flags, WindowStateAnimator animator, int windowType, int ownerUid) {
mAnimator = animator;
@@ -89,16 +93,16 @@ class WindowSurfaceController {
title = name;
mService = animator.mService;
+ final WindowState win = animator.mWin;
+ mWindowType = windowType;
+ mWindowSession = win.mSession;
- // For opaque child windows placed under parent windows,
- // we use a special SurfaceControl which mirrors commands
- // to a black-out layer placed one Z-layer below the surface.
+ // For opaque child windows placed under parent windows, we use a special SurfaceControl
+ // which mirrors commands to a black-out layer placed one Z-layer below the surface.
// This prevents holes to whatever app/wallpaper is underneath.
- if (animator.mWin.isChildWindow() &&
- animator.mWin.mSubLayer < 0 &&
- animator.mWin.mAppToken != null) {
- mSurfaceControl = new SurfaceControlWithBackground(s,
- name, w, h, format, flags, animator.mWin.mAppToken, windowType, ownerUid);
+ if (win.isChildWindow() && win.mSubLayer < 0 && win.mAppToken != null) {
+ mSurfaceControl = new SurfaceControlWithBackground(
+ s, name, w, h, format, flags, win.mAppToken, windowType, ownerUid);
} else if (DEBUG_SURFACE_TRACE) {
mSurfaceControl = new SurfaceTrace(
s, name, w, h, format, flags, windowType, ownerUid);
@@ -109,8 +113,7 @@ class WindowSurfaceController {
if (mService.mRoot.mSurfaceTraceEnabled) {
mSurfaceControl = new RemoteSurfaceTrace(
- mService.mRoot.mSurfaceTraceFd.getFileDescriptor(),
- mSurfaceControl, animator.mWin);
+ mService.mRoot.mSurfaceTraceFd.getFileDescriptor(), mSurfaceControl, win);
}
}
@@ -141,13 +144,14 @@ class WindowSurfaceController {
}
private void hideSurface() {
- if (mSurfaceControl != null) {
- mSurfaceShown = false;
- try {
- mSurfaceControl.hide();
- } catch (RuntimeException e) {
- Slog.w(TAG, "Exception hiding surface in " + this);
- }
+ if (mSurfaceControl == null) {
+ return;
+ }
+ setShown(false);
+ try {
+ mSurfaceControl.hide();
+ } catch (RuntimeException e) {
+ Slog.w(TAG, "Exception hiding surface in " + this);
}
}
@@ -165,7 +169,7 @@ class WindowSurfaceController {
mSurfaceControl.setLayer(layer);
mSurfaceControl.setAlpha(0);
- mSurfaceShown = false;
+ setShown(false);
} catch (RuntimeException e) {
Slog.w(TAG, "Error creating surface in " + this, e);
mAnimator.reclaimSomeSurfaceMemory("create-init", true);
@@ -188,7 +192,7 @@ class WindowSurfaceController {
} catch (RuntimeException e) {
Slog.w(TAG, "Error destroying surface in: " + this, e);
} finally {
- mSurfaceShown = false;
+ setShown(false);
mSurfaceControl = null;
}
}
@@ -447,7 +451,7 @@ class WindowSurfaceController {
private boolean showSurface() {
try {
- mSurfaceShown = true;
+ setShown(true);
mSurfaceControl.show();
return true;
} catch (RuntimeException e) {
@@ -515,6 +519,10 @@ class WindowSurfaceController {
void setShown(boolean surfaceShown) {
mSurfaceShown = surfaceShown;
+
+ if (mWindowSession != null) {
+ mWindowSession.onWindowSurfaceVisibilityChanged(this, mSurfaceShown, mWindowType);
+ }
}
float getX() {