diff options
| author | 2017-02-18 00:11:37 +0000 | |
|---|---|---|
| committer | 2017-02-18 00:11:41 +0000 | |
| commit | 4b441535c32252d12663f0fa2d7178472fe82d4d (patch) | |
| tree | dfd13a21af2b66dffb9ebb9faa92d875649067bf | |
| parent | 18c76bb197327859fc88ea9e2ead52495033e27a (diff) | |
| parent | 387e4c61338ddf7aee89d10c8aac329e9562b831 (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.xml | 1 | ||||
| -rw-r--r-- | core/res/res/drawable-nodpi/alert_window_layer.xml | 24 | ||||
| -rw-r--r-- | core/res/res/values/strings.xml | 15 | ||||
| -rw-r--r-- | core/res/res/values/symbols.xml | 8 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/AlertWindowNotification.java | 144 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/Session.java | 91 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowManagerService.java | 55 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowState.java | 4 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowSurfaceController.java | 48 |
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() { |