blob: 0e192eab498fb4fbe4579f7e8edcadecfb847a65 [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;
22import android.content.ComponentName;
23import android.content.IIntentReceiver;
24import android.content.Intent;
25import android.content.pm.ResolveInfo;
26import android.os.Bundle;
27import android.os.Process;
28import android.os.UserHandle;
29import android.util.Slog;
30
31import com.android.internal.R;
32import com.android.internal.util.ProgressReporter;
33
34import java.util.List;
35
36/**
37 * Simple broadcaster that sends {@link Intent#ACTION_PRE_BOOT_COMPLETED} to all
38 * system apps that register for it. Override {@link #onFinished()} to handle
39 * when all broadcasts are finished.
40 */
41public abstract class PreBootBroadcaster extends IIntentReceiver.Stub {
42 private static final String TAG = "PreBootBroadcaster";
43
44 private final ActivityManagerService mService;
45 private final int mUserId;
46 private final ProgressReporter mProgress;
47
48 private final Intent mIntent;
49 private final List<ResolveInfo> mTargets;
50
51 private int mIndex = 0;
52
53 public PreBootBroadcaster(ActivityManagerService service, int userId,
54 ProgressReporter progress) {
55 mService = service;
56 mUserId = userId;
57 mProgress = progress;
58
59 mIntent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
60 mIntent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
61
62 mTargets = mService.mContext.getPackageManager().queryBroadcastReceiversAsUser(mIntent,
63 MATCH_SYSTEM_ONLY, UserHandle.of(userId));
64 }
65
66 public void sendNext() {
67 if (mIndex >= mTargets.size()) {
68 onFinished();
69 return;
70 }
71
Jeff Sharkey100bd9c2016-04-11 16:00:54 -060072 if (!mService.isUserRunning(mUserId, 0)) {
73 Slog.i(TAG, "User " + mUserId + " is no longer running; skipping remaining receivers");
74 onFinished();
75 return;
76 }
77
Jeff Sharkeybd91e2f2016-03-22 15:32:31 -060078 final ResolveInfo ri = mTargets.get(mIndex++);
79 final ComponentName componentName = ri.activityInfo.getComponentName();
80
81 final CharSequence label = ri.activityInfo.loadLabel(mService.mContext.getPackageManager());
82 mProgress.setProgress(mIndex, mTargets.size(),
83 mService.mContext.getString(R.string.android_preparing_apk, label));
84
85 Slog.i(TAG, "Pre-boot of " + componentName.toShortString() + " for user " + mUserId);
86 EventLogTags.writeAmPreBoot(mUserId, componentName.getPackageName());
87
88 mIntent.setComponent(componentName);
89 mService.broadcastIntentLocked(null, null, mIntent, null, this, 0, null, null, null,
90 AppOpsManager.OP_NONE, null, true, false, ActivityManagerService.MY_PID,
91 Process.SYSTEM_UID, mUserId);
92 }
93
94 @Override
95 public void performReceive(Intent intent, int resultCode, String data, Bundle extras,
96 boolean ordered, boolean sticky, int sendingUser) {
97 sendNext();
98 }
99
100 public abstract void onFinished();
101}