/*
 * 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.NotificationManager.IMPORTANCE_MIN;
import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
import static android.content.Context.NOTIFICATION_SERVICE;
import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.provider.Settings.ACTION_MANAGE_OVERLAY_PERMISSION;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
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.Drawable;

import android.net.Uri;
import com.android.internal.R;
import com.android.server.policy.IconUtilities;

/** 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 static NotificationChannelGroup sChannelGroup;
    private final int mRequestCode;
    private final WindowManagerService mService;
    private String mNotificationTag;
    private final NotificationManager mNotificationManager;
    private final String mPackageName;
    private boolean mPosted;
    private IconUtilities mIconUtilities;

    AlertWindowNotification(WindowManagerService service, String packageName) {
        mService = service;
        mPackageName = packageName;
        mNotificationManager =
                (NotificationManager) mService.mContext.getSystemService(NOTIFICATION_SERVICE);
        mNotificationTag = CHANNEL_PREFIX + mPackageName;
        mRequestCode = sNextRequestCode++;
        mIconUtilities = new IconUtilities(mService.mContext);
    }

    void post() {
        // 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::onPostNotification);
    }

    /** Cancels the notification */
    void cancel() {
        // We can't call into NotificationManager with WM lock held since it might call into AM.
        // So, we post a message to do it later.
        mService.mH.post(this::onCancelNotification);
    }

    /** Don't call with the window manager lock held! */
    private void onCancelNotification() {
        if (!mPosted) {
            // Notification isn't currently posted...
            return;
        }
        mPosted = false;
        mNotificationManager.cancel(mNotificationTag, NOTIFICATION_ID);
    }

    /** Don't call with the window manager lock held! */
    private void onPostNotification() {
        if (mPosted) {
            // Notification already posted...
            return;
        }
        mPosted = true;

        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;

        createNotificationChannel(context, appName);

        final String message = context.getString(R.string.alert_windows_notification_message,
                appName);
        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)
                .setContentIntent(getContentIntent(context, mPackageName));

        if (aInfo != null) {
            final Drawable drawable = pm.getApplicationIcon(aInfo);
            if (drawable != null) {
                final Bitmap bitmap = mIconUtilities.createIconBitmap(drawable);
                builder.setLargeIcon(bitmap);
            }
        }

        mNotificationManager.notify(mNotificationTag, NOTIFICATION_ID, builder.build());
    }

    private PendingIntent getContentIntent(Context context, String packageName) {
        final Intent intent = new Intent(ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.fromParts("package", packageName, null));
        intent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK);
        // Calls into activity manager...
        return PendingIntent.getActivity(context, mRequestCode, intent, FLAG_CANCEL_CURRENT);
    }

    private void createNotificationChannel(Context context, String appName) {
        if (sChannelGroup == null) {
            sChannelGroup = new NotificationChannelGroup(CHANNEL_PREFIX,
                    mService.mContext.getString(
                            R.string.alert_windows_notification_channel_group_name));
            mNotificationManager.createNotificationChannelGroup(sChannelGroup);
        }

        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);
        channel.setBlockableSystem(true);
        channel.setGroup(sChannelGroup.getId());
        mNotificationManager.createNotificationChannel(channel);
    }


    private ApplicationInfo getApplicationInfo(PackageManager pm, String packageName) {
        try {
            return pm.getApplicationInfo(packageName, 0);
        } catch (PackageManager.NameNotFoundException e) {
            return null;
        }
    }
}
