• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 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 
17 package com.android.server.am;
18 
19 import android.annotation.IntDef;
20 import android.compat.annotation.ChangeId;
21 import android.compat.annotation.EnabledAfter;
22 import android.compat.annotation.Overridable;
23 import android.content.ContentResolver;
24 import android.database.ContentObserver;
25 import android.os.Build;
26 import android.os.Handler;
27 import android.provider.Settings;
28 import android.util.KeyValueListParser;
29 import android.util.Slog;
30 import android.util.TimeUtils;
31 
32 import java.io.PrintWriter;
33 import java.lang.annotation.Retention;
34 import java.lang.annotation.RetentionPolicy;
35 
36 /**
37  * Tunable parameters for broadcast dispatch policy
38  */
39 public class BroadcastConstants {
40     private static final String TAG = "BroadcastConstants";
41 
42     // Value element names within the Settings record
43     static final String KEY_TIMEOUT = "bcast_timeout";
44     static final String KEY_SLOW_TIME = "bcast_slow_time";
45     static final String KEY_DEFERRAL = "bcast_deferral";
46     static final String KEY_DEFERRAL_DECAY_FACTOR = "bcast_deferral_decay_factor";
47     static final String KEY_DEFERRAL_FLOOR = "bcast_deferral_floor";
48     static final String KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT =
49             "bcast_allow_bg_activity_start_timeout";
50 
51     // All time intervals are in milliseconds
52     private static final long DEFAULT_TIMEOUT = 10_000 * Build.HW_TIMEOUT_MULTIPLIER;
53     private static final long DEFAULT_SLOW_TIME = 5_000 * Build.HW_TIMEOUT_MULTIPLIER;
54     private static final long DEFAULT_DEFERRAL = 5_000 * Build.HW_TIMEOUT_MULTIPLIER;
55     private static final float DEFAULT_DEFERRAL_DECAY_FACTOR = 0.75f;
56     private static final long DEFAULT_DEFERRAL_FLOOR = 0;
57     private static final long DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT =
58             10_000 * Build.HW_TIMEOUT_MULTIPLIER;
59 
60     /**
61      * Defer LOCKED_BOOT_COMPLETED and BOOT_COMPLETED broadcasts until the first time any process in
62      * the UID is started.
63      */
64     @ChangeId
65     @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.S_V2)
66     @Overridable
67     static final long DEFER_BOOT_COMPLETED_BROADCAST_CHANGE_ID = 203704822L;
68 
69     /**
70      * Do not defer LOCKED_BOOT_COMPLETED and BOOT_COMPLETED broadcasts.
71      */
72     public static final int DEFER_BOOT_COMPLETED_BROADCAST_NONE = 0;
73     /**
74      * Defer all LOCKED_BOOT_COMPLETED and BOOT_COMPLETED broadcasts.
75      */
76     public static final int DEFER_BOOT_COMPLETED_BROADCAST_ALL = 1 << 0;
77     /**
78      * Defer LOCKED_BOOT_COMPLETED and BOOT_COMPLETED broadcasts if app is background restricted.
79      */
80     public static final int DEFER_BOOT_COMPLETED_BROADCAST_BACKGROUND_RESTRICTED_ONLY = 1 << 1;
81     /**
82      * Defer LOCKED_BOOT_COMPLETED and BOOT_COMPLETED broadcasts if app's targetSdkVersion is T
83      * and above.
84      */
85     public static final int DEFER_BOOT_COMPLETED_BROADCAST_TARGET_T_ONLY = 1 << 2;
86 
87     /**
88      * The list of DEFER_BOOT_COMPLETED_BROADCAST types.
89      * If multiple flags are selected, all conditions must be met to defer the broadcast.
90      * @hide
91      */
92     @IntDef(flag = true, prefix = { "DEFER_BOOT_COMPLETED_BROADCAST_" }, value = {
93             DEFER_BOOT_COMPLETED_BROADCAST_NONE,
94             DEFER_BOOT_COMPLETED_BROADCAST_ALL,
95             DEFER_BOOT_COMPLETED_BROADCAST_BACKGROUND_RESTRICTED_ONLY,
96             DEFER_BOOT_COMPLETED_BROADCAST_TARGET_T_ONLY,
97     })
98     @Retention(RetentionPolicy.SOURCE)
99     public @interface DeferBootCompletedBroadcastType {}
100 
101     // All time constants are in milliseconds
102 
103     // Timeout period for this broadcast queue
104     public long TIMEOUT = DEFAULT_TIMEOUT;
105     // Handling time above which we declare that a broadcast recipient was "slow".  Any
106     // value <= zero is interpreted as disabling broadcast deferral policy entirely.
107     public long SLOW_TIME = DEFAULT_SLOW_TIME;
108     // How long to initially defer broadcasts, if an app is slow to handle one
109     public long DEFERRAL = DEFAULT_DEFERRAL;
110     // Decay factor for successive broadcasts' deferral time
111     public float DEFERRAL_DECAY_FACTOR = DEFAULT_DEFERRAL_DECAY_FACTOR;
112     // Minimum that the deferral time can decay to until the backlog fully clears
113     public long DEFERRAL_FLOOR = DEFAULT_DEFERRAL_FLOOR;
114     // For a receiver that has been allowed to start background activities, how long after it
115     // started its process can start a background activity.
116     public long ALLOW_BG_ACTIVITY_START_TIMEOUT = DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT;
117 
118     // Settings override tracking for this instance
119     private String mSettingsKey;
120     private SettingsObserver mSettingsObserver;
121     private ContentResolver mResolver;
122     private final KeyValueListParser mParser = new KeyValueListParser(',');
123 
124     class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler)125         SettingsObserver(Handler handler) {
126             super(handler);
127         }
128 
129         @Override
onChange(boolean selfChange)130         public void onChange(boolean selfChange) {
131             updateConstants();
132         }
133     }
134 
135     // A given constants instance is configured to observe specific keys from which
136     // that instance's values are drawn.
BroadcastConstants(String settingsKey)137     public BroadcastConstants(String settingsKey) {
138         mSettingsKey = settingsKey;
139     }
140 
141     /**
142      * Spin up the observer lazily, since it can only happen once the settings provider
143      * has been brought into service
144      */
startObserving(Handler handler, ContentResolver resolver)145     public void startObserving(Handler handler, ContentResolver resolver) {
146         mResolver = resolver;
147 
148         mSettingsObserver = new SettingsObserver(handler);
149         mResolver.registerContentObserver(Settings.Global.getUriFor(mSettingsKey),
150                 false, mSettingsObserver);
151 
152         updateConstants();
153     }
154 
updateConstants()155     private void updateConstants() {
156         synchronized (mParser) {
157             try {
158                 mParser.setString(Settings.Global.getString(mResolver, mSettingsKey));
159             } catch (IllegalArgumentException e) {
160                 Slog.e(TAG, "Bad broadcast settings in key '" + mSettingsKey + "'", e);
161                 return;
162             }
163 
164             // Unspecified fields retain their current value rather than revert to default
165             TIMEOUT = mParser.getLong(KEY_TIMEOUT, TIMEOUT);
166             SLOW_TIME = mParser.getLong(KEY_SLOW_TIME, SLOW_TIME);
167             DEFERRAL = mParser.getLong(KEY_DEFERRAL, DEFERRAL);
168             DEFERRAL_DECAY_FACTOR = mParser.getFloat(KEY_DEFERRAL_DECAY_FACTOR,
169                     DEFERRAL_DECAY_FACTOR);
170             DEFERRAL_FLOOR = mParser.getLong(KEY_DEFERRAL_FLOOR, DEFERRAL_FLOOR);
171             ALLOW_BG_ACTIVITY_START_TIMEOUT = mParser.getLong(KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT,
172                     ALLOW_BG_ACTIVITY_START_TIMEOUT);
173         }
174     }
175 
176     /**
177      * Standard dumpsys support; invoked from BroadcastQueue dump
178      */
dump(PrintWriter pw)179     public void dump(PrintWriter pw) {
180         synchronized (mParser) {
181             pw.println();
182             pw.print("  Broadcast parameters (key=");
183             pw.print(mSettingsKey);
184             pw.print(", observing=");
185             pw.print(mSettingsObserver != null);
186             pw.println("):");
187 
188             pw.print("    "); pw.print(KEY_TIMEOUT); pw.print(" = ");
189             TimeUtils.formatDuration(TIMEOUT, pw);
190             pw.println();
191 
192             pw.print("    "); pw.print(KEY_SLOW_TIME); pw.print(" = ");
193             TimeUtils.formatDuration(SLOW_TIME, pw);
194             pw.println();
195 
196             pw.print("    "); pw.print(KEY_DEFERRAL); pw.print(" = ");
197             TimeUtils.formatDuration(DEFERRAL, pw);
198             pw.println();
199 
200             pw.print("    "); pw.print(KEY_DEFERRAL_DECAY_FACTOR); pw.print(" = ");
201             pw.println(DEFERRAL_DECAY_FACTOR);
202 
203             pw.print("    "); pw.print(KEY_DEFERRAL_FLOOR); pw.print(" = ");
204             TimeUtils.formatDuration(DEFERRAL_FLOOR, pw);
205 
206             pw.print("    "); pw.print(KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT); pw.print(" = ");
207             TimeUtils.formatDuration(ALLOW_BG_ACTIVITY_START_TIMEOUT, pw);
208             pw.println();
209         }
210     }
211 }
212