Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4b441535 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes Ie28325b6,I4e406a94

* changes:
  Display on-going notification for apps using alert windows.
  Set importance for processes displaying app-overlays based on visibility
parents 18c76bb1 387e4c61
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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                           -->
+24 −0
Original line number Diff line number Diff line
<!--
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>
+15 −0
Original line number Diff line number Diff line
@@ -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 />

+8 −0
Original line number Diff line number Diff line
@@ -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>
+144 −0
Original line number Diff line number Diff line
/*
 * 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;
        }
    }
}
Loading