blob: 747e8a89f8e73d5a527814d2c01fedfa88368e1f [file] [log] [blame]
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -06001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License
15 */
16
17package com.android.server.am;
18
19import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
20
21import android.app.AppOpsManager;
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -060022import android.app.Notification;
23import android.app.NotificationManager;
Jeff Sharkey288414e2016-07-18 18:29:48 -060024import android.app.PendingIntent;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060025import android.content.ComponentName;
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -060026import android.content.Context;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060027import android.content.IIntentReceiver;
28import android.content.Intent;
29import android.content.pm.ResolveInfo;
Michal Karpinskic99d7182019-02-17 13:15:23 +000030import android.os.Binder;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060031import android.os.Bundle;
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -060032import android.os.Handler;
33import android.os.Message;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060034import android.os.Process;
35import android.os.UserHandle;
36import android.util.Slog;
37
38import com.android.internal.R;
Chris Wren282cfef2017-03-27 15:01:44 -040039import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
Geoffrey Pitschaf759c52017-02-15 09:35:38 -050040import com.android.internal.notification.SystemNotificationChannels;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060041import com.android.internal.util.ProgressReporter;
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -060042import com.android.server.UiThread;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060043
44import java.util.List;
45
46/**
47 * Simple broadcaster that sends {@link Intent#ACTION_PRE_BOOT_COMPLETED} to all
48 * system apps that register for it. Override {@link #onFinished()} to handle
49 * when all broadcasts are finished.
50 */
51public abstract class PreBootBroadcaster extends IIntentReceiver.Stub {
52 private static final String TAG = "PreBootBroadcaster";
53
54 private final ActivityManagerService mService;
55 private final int mUserId;
56 private final ProgressReporter mProgress;
Jeff Sharkey288414e2016-07-18 18:29:48 -060057 private final boolean mQuiet;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060058
59 private final Intent mIntent;
60 private final List<ResolveInfo> mTargets;
61
62 private int mIndex = 0;
63
64 public PreBootBroadcaster(ActivityManagerService service, int userId,
Jeff Sharkey24d94912016-07-07 12:33:48 -060065 ProgressReporter progress, boolean quiet) {
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060066 mService = service;
67 mUserId = userId;
68 mProgress = progress;
Jeff Sharkey288414e2016-07-18 18:29:48 -060069 mQuiet = quiet;
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060070
71 mIntent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
72 mIntent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
73
74 mTargets = mService.mContext.getPackageManager().queryBroadcastReceiversAsUser(mIntent,
75 MATCH_SYSTEM_ONLY, UserHandle.of(userId));
76 }
77
78 public void sendNext() {
79 if (mIndex >= mTargets.size()) {
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -060080 mHandler.obtainMessage(MSG_HIDE).sendToTarget();
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060081 onFinished();
82 return;
83 }
84
Jeff Sharkey100bd9c2016-04-11 16:00:54 -060085 if (!mService.isUserRunning(mUserId, 0)) {
86 Slog.i(TAG, "User " + mUserId + " is no longer running; skipping remaining receivers");
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -060087 mHandler.obtainMessage(MSG_HIDE).sendToTarget();
Jeff Sharkey100bd9c2016-04-11 16:00:54 -060088 onFinished();
89 return;
90 }
91
Jeff Sharkey288414e2016-07-18 18:29:48 -060092 if (!mQuiet) {
93 mHandler.obtainMessage(MSG_SHOW, mTargets.size(), mIndex).sendToTarget();
94 }
95
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060096 final ResolveInfo ri = mTargets.get(mIndex++);
97 final ComponentName componentName = ri.activityInfo.getComponentName();
98
Jeff Sharkeyfd241082016-04-19 15:58:24 -060099 if (mProgress != null) {
100 final CharSequence label = ri.activityInfo
101 .loadLabel(mService.mContext.getPackageManager());
102 mProgress.setProgress(mIndex, mTargets.size(),
103 mService.mContext.getString(R.string.android_preparing_apk, label));
104 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600105
106 Slog.i(TAG, "Pre-boot of " + componentName.toShortString() + " for user " + mUserId);
107 EventLogTags.writeAmPreBoot(mUserId, componentName.getPackageName());
108
109 mIntent.setComponent(componentName);
Christopher Tateeb4f5282019-05-13 14:26:19 -0700110 synchronized (mService) {
Philip P. Moltmann9c5226f2020-01-10 08:53:43 -0800111 mService.broadcastIntentLocked(null, null, null, mIntent, null, this, 0, null, null,
112 null, AppOpsManager.OP_NONE, null, true, false, ActivityManagerService.MY_PID,
Christopher Tateeb4f5282019-05-13 14:26:19 -0700113 Process.SYSTEM_UID, Binder.getCallingUid(), Binder.getCallingPid(), mUserId);
114 }
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600115 }
116
117 @Override
118 public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
119 boolean ordered, boolean sticky, int sendingUser) {
120 sendNext();
121 }
122
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -0600123 private static final int MSG_SHOW = 1;
124 private static final int MSG_HIDE = 2;
125
126 private Handler mHandler = new Handler(UiThread.get().getLooper(), null, true) {
127 @Override
128 public void handleMessage(Message msg) {
129 final Context context = mService.mContext;
130 final NotificationManager notifManager = context
131 .getSystemService(NotificationManager.class);
Jeff Sharkey288414e2016-07-18 18:29:48 -0600132 final int max = msg.arg1;
133 final int index = msg.arg2;
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -0600134
135 switch (msg.what) {
136 case MSG_SHOW:
137 final CharSequence title = context
Jeff Sharkeya4600cc2016-07-29 16:39:16 -0600138 .getText(R.string.android_upgrading_notification_title);
Jeff Sharkey288414e2016-07-18 18:29:48 -0600139
140 final Intent intent = new Intent();
141 intent.setClassName("com.android.settings",
142 "com.android.settings.HelpTrampoline");
143 intent.putExtra(Intent.EXTRA_TEXT, "help_url_upgrading");
144
145 final PendingIntent contentIntent;
146 if (context.getPackageManager().resolveActivity(intent, 0) != null) {
147 contentIntent = PendingIntent.getActivity(context, 0, intent, 0);
148 } else {
149 contentIntent = null;
150 }
151
Geoffrey Pitschaf759c52017-02-15 09:35:38 -0500152 final Notification notif =
153 new Notification.Builder(mService.mContext,
154 SystemNotificationChannels.UPDATES)
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -0600155 .setSmallIcon(R.drawable.stat_sys_adb)
156 .setWhen(0)
157 .setOngoing(true)
158 .setTicker(title)
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -0600159 .setColor(context.getColor(
160 com.android.internal.R.color.system_notification_accent_color))
161 .setContentTitle(title)
Jeff Sharkey288414e2016-07-18 18:29:48 -0600162 .setContentIntent(contentIntent)
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -0600163 .setVisibility(Notification.VISIBILITY_PUBLIC)
Jeff Sharkey288414e2016-07-18 18:29:48 -0600164 .setProgress(max, index, false)
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -0600165 .build();
Chris Wren282cfef2017-03-27 15:01:44 -0400166 notifManager.notifyAsUser(TAG, SystemMessage.NOTE_SYSTEM_UPGRADING, notif,
167 UserHandle.of(mUserId));
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -0600168 break;
169
170 case MSG_HIDE:
Chris Wren282cfef2017-03-27 15:01:44 -0400171 notifManager.cancelAsUser(TAG, SystemMessage.NOTE_SYSTEM_UPGRADING,
172 UserHandle.of(mUserId));
Jeff Sharkeyc4bcacb2016-06-28 12:33:12 -0600173 break;
174 }
175 }
176 };
177
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -0600178 public abstract void onFinished();
179}