From 44dbe294fbf06a1def61c48e758621e61ce23b08 Mon Sep 17 00:00:00 2001 From: Winson Date: Thu, 10 Mar 2016 14:00:14 -0800 Subject: [PATCH] Fixing issue where screenshot notification remains non-dismissible. - Ensure that we start the screenshot as a foreground service to reduce likelihood that it is killed while taking a screenshot. - If the screenshot process times out or gets killed for any reason, ensure that we update the notification with an appropriate error message. Bug: 27389179 Change-Id: I5007bda95538044bc753e4ceffd2f59a069c857b --- packages/SystemUI/AndroidManifest.xml | 9 +++++ packages/SystemUI/res/values/strings.xml | 4 ++- .../screenshot/ScreenshotServiceErrorReceiver.java | 40 ++++++++++++++++++++++ .../android/server/policy/PhoneWindowManager.java | 39 +++++++++++++++++---- 4 files changed, 84 insertions(+), 8 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 637551c68a74..334035cb5dff 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -187,6 +187,15 @@ android:process=":screenshot" android:exported="false" /> + + + + + + + diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 7838fea7722c..8af413c4816c 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -185,7 +185,9 @@ Touch to view your screenshot. Couldn\'t capture screenshot. - + + Problem encountered while saving screenshot. + Can\'t save screenshot due to limited storage space. Taking screenshots is not allowed by the app or your organization. diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java new file mode 100644 index 000000000000..fc2a1e47253c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 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.systemui.screenshot; + +import android.app.NotificationManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import com.android.systemui.R; + +/** + * Performs a number of miscellaneous, non-system-critical actions + * after the system has finished booting. + */ +public class ScreenshotServiceErrorReceiver extends BroadcastReceiver { + + @Override + public void onReceive(final Context context, Intent intent) { + // Show a message that we've failed to save the image to disk + NotificationManager nm = (NotificationManager) + context.getSystemService(Context.NOTIFICATION_SERVICE); + GlobalScreenshot.notifyScreenshotError(context, nm, + R.string.screenshot_failed_to_save_unknown_text); + } +} diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 0cd69c42ee72..76a93d49fd9c 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -251,6 +251,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { // app shows again. If that doesn't happen for 30s we drop the gesture. private static final long PANIC_GESTURE_EXPIRATION = 30000; + private static final String SYSUI_PACKAGE = "com.android.systemui"; + private static final String SYSUI_SCREENSHOT_SERVICE = + "com.android.systemui.screenshot.TakeScreenshotService"; + private static final String SYSUI_SCREENSHOT_ERROR_RECEIVER = + "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver"; + /** * Keyguard stuff */ @@ -5186,6 +5192,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mScreenshotConnection != null) { mContext.unbindService(mScreenshotConnection); mScreenshotConnection = null; + notifyScreenshotError(); } } } @@ -5197,10 +5204,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mScreenshotConnection != null) { return; } - ComponentName cn = new ComponentName("com.android.systemui", - "com.android.systemui.screenshot.TakeScreenshotService"); - Intent intent = new Intent(); - intent.setComponent(cn); + final ComponentName serviceComponent = new ComponentName(SYSUI_PACKAGE, + SYSUI_SCREENSHOT_SERVICE); + final Intent serviceIntent = new Intent(); + serviceIntent.setComponent(serviceComponent); ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { @@ -5235,17 +5242,35 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } } + @Override - public void onServiceDisconnected(ComponentName name) {} + public void onServiceDisconnected(ComponentName name) { + notifyScreenshotError(); + } }; - if (mContext.bindServiceAsUser( - intent, conn, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) { + if (mContext.bindServiceAsUser(serviceIntent, conn, + Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, + UserHandle.CURRENT)) { mScreenshotConnection = conn; mHandler.postDelayed(mScreenshotTimeout, 10000); } } } + /** + * Notifies the screenshot service to show an error. + */ + private void notifyScreenshotError() { + // If the service process is killed, then ask it to clean up after itself + final ComponentName errorComponent = new ComponentName(SYSUI_PACKAGE, + SYSUI_SCREENSHOT_ERROR_RECEIVER); + Intent errorIntent = new Intent(); + errorIntent.setComponent(errorComponent); + errorIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | + Intent.FLAG_RECEIVER_FOREGROUND); + mContext.sendBroadcastAsUser(errorIntent, UserHandle.ALL); + } + /** {@inheritDoc} */ @Override public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { -- 2.11.0