/*
 * 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.server.am;

import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;

import android.app.AppOpsManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.os.UserHandle;
import android.util.Slog;

import com.android.internal.R;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.ProgressReporter;
import com.android.server.UiThread;

import java.util.List;

/**
 * Simple broadcaster that sends {@link Intent#ACTION_PRE_BOOT_COMPLETED} to all
 * system apps that register for it. Override {@link #onFinished()} to handle
 * when all broadcasts are finished.
 */
public abstract class PreBootBroadcaster extends IIntentReceiver.Stub {
    private static final String TAG = "PreBootBroadcaster";

    private final ActivityManagerService mService;
    private final int mUserId;
    private final ProgressReporter mProgress;
    private final boolean mQuiet;

    private final Intent mIntent;
    private final List<ResolveInfo> mTargets;

    private int mIndex = 0;

    public PreBootBroadcaster(ActivityManagerService service, int userId,
            ProgressReporter progress, boolean quiet) {
        mService = service;
        mUserId = userId;
        mProgress = progress;
        mQuiet = quiet;

        mIntent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
        mIntent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);

        mTargets = mService.mContext.getPackageManager().queryBroadcastReceiversAsUser(mIntent,
                MATCH_SYSTEM_ONLY, UserHandle.of(userId));
    }

    public void sendNext() {
        if (mIndex >= mTargets.size()) {
            mHandler.obtainMessage(MSG_HIDE).sendToTarget();
            onFinished();
            return;
        }

        if (!mService.isUserRunning(mUserId, 0)) {
            Slog.i(TAG, "User " + mUserId + " is no longer running; skipping remaining receivers");
            mHandler.obtainMessage(MSG_HIDE).sendToTarget();
            onFinished();
            return;
        }

        if (!mQuiet) {
            mHandler.obtainMessage(MSG_SHOW, mTargets.size(), mIndex).sendToTarget();
        }

        final ResolveInfo ri = mTargets.get(mIndex++);
        final ComponentName componentName = ri.activityInfo.getComponentName();

        if (mProgress != null) {
            final CharSequence label = ri.activityInfo
                    .loadLabel(mService.mContext.getPackageManager());
            mProgress.setProgress(mIndex, mTargets.size(),
                    mService.mContext.getString(R.string.android_preparing_apk, label));
        }

        Slog.i(TAG, "Pre-boot of " + componentName.toShortString() + " for user " + mUserId);
        EventLogTags.writeAmPreBoot(mUserId, componentName.getPackageName());

        mIntent.setComponent(componentName);
        synchronized (mService) {
            mService.broadcastIntentLocked(null, null, mIntent, null, this, 0, null, null, null,
                    AppOpsManager.OP_NONE, null, true, false, ActivityManagerService.MY_PID,
                    Process.SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), mUserId);
        }
    }

    @Override
    public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
            boolean ordered, boolean sticky, int sendingUser) {
        sendNext();
    }

    private static final int MSG_SHOW = 1;
    private static final int MSG_HIDE = 2;

    private Handler mHandler = new Handler(UiThread.get().getLooper(), null, true) {
        @Override
        public void handleMessage(Message msg) {
            final Context context = mService.mContext;
            final NotificationManager notifManager = context
                    .getSystemService(NotificationManager.class);
            final int max = msg.arg1;
            final int index = msg.arg2;

            switch (msg.what) {
                case MSG_SHOW:
                    final CharSequence title = context
                            .getText(R.string.android_upgrading_notification_title);

                    final Intent intent = new Intent();
                    intent.setClassName("com.android.settings",
                            "com.android.settings.HelpTrampoline");
                    intent.putExtra(Intent.EXTRA_TEXT, "help_url_upgrading");

                    final PendingIntent contentIntent;
                    if (context.getPackageManager().resolveActivity(intent, 0) != null) {
                        contentIntent = PendingIntent.getActivity(context, 0, intent, 0);
                    } else {
                        contentIntent = null;
                    }

                    final Notification notif =
                            new Notification.Builder(mService.mContext,
                                    SystemNotificationChannels.UPDATES)
                            .setSmallIcon(R.drawable.stat_sys_adb)
                            .setWhen(0)
                            .setOngoing(true)
                            .setTicker(title)
                            .setColor(context.getColor(
                                    com.android.internal.R.color.system_notification_accent_color))
                            .setContentTitle(title)
                            .setContentIntent(contentIntent)
                            .setVisibility(Notification.VISIBILITY_PUBLIC)
                            .setProgress(max, index, false)
                            .build();
                    notifManager.notifyAsUser(TAG, SystemMessage.NOTE_SYSTEM_UPGRADING, notif,
                            UserHandle.of(mUserId));
                    break;

                case MSG_HIDE:
                    notifManager.cancelAsUser(TAG, SystemMessage.NOTE_SYSTEM_UPGRADING,
                            UserHandle.of(mUserId));
                    break;
            }
        }
    };

    public abstract void onFinished();
}
