• 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.content.ContentResolver;
20 import android.database.ContentObserver;
21 import android.os.Build;
22 import android.os.Handler;
23 import android.provider.Settings;
24 import android.util.KeyValueListParser;
25 import android.util.Slog;
26 import android.util.TimeUtils;
27 
28 import java.io.PrintWriter;
29 
30 /**
31  * Tunable parameters for broadcast dispatch policy
32  */
33 public class BroadcastConstants {
34     private static final String TAG = "BroadcastConstants";
35 
36     // Value element names within the Settings record
37     static final String KEY_TIMEOUT = "bcast_timeout";
38     static final String KEY_SLOW_TIME = "bcast_slow_time";
39     static final String KEY_DEFERRAL = "bcast_deferral";
40     static final String KEY_DEFERRAL_DECAY_FACTOR = "bcast_deferral_decay_factor";
41     static final String KEY_DEFERRAL_FLOOR = "bcast_deferral_floor";
42     static final String KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT =
43             "bcast_allow_bg_activity_start_timeout";
44 
45     // All time intervals are in milliseconds
46     private static final long DEFAULT_TIMEOUT = 10_000 * Build.HW_TIMEOUT_MULTIPLIER;
47     private static final long DEFAULT_SLOW_TIME = 5_000 * Build.HW_TIMEOUT_MULTIPLIER;
48     private static final long DEFAULT_DEFERRAL = 5_000 * Build.HW_TIMEOUT_MULTIPLIER;
49     private static final float DEFAULT_DEFERRAL_DECAY_FACTOR = 0.75f;
50     private static final long DEFAULT_DEFERRAL_FLOOR = 0;
51     private static final long DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT =
52             10_000 * Build.HW_TIMEOUT_MULTIPLIER;
53 
54     // All time constants are in milliseconds
55 
56     // Timeout period for this broadcast queue
57     public long TIMEOUT = DEFAULT_TIMEOUT;
58     // Handling time above which we declare that a broadcast recipient was "slow".  Any
59     // value <= zero is interpreted as disabling broadcast deferral policy entirely.
60     public long SLOW_TIME = DEFAULT_SLOW_TIME;
61     // How long to initially defer broadcasts, if an app is slow to handle one
62     public long DEFERRAL = DEFAULT_DEFERRAL;
63     // Decay factor for successive broadcasts' deferral time
64     public float DEFERRAL_DECAY_FACTOR = DEFAULT_DEFERRAL_DECAY_FACTOR;
65     // Minimum that the deferral time can decay to until the backlog fully clears
66     public long DEFERRAL_FLOOR = DEFAULT_DEFERRAL_FLOOR;
67     // For a receiver that has been allowed to start background activities, how long after it
68     // started its process can start a background activity.
69     public long ALLOW_BG_ACTIVITY_START_TIMEOUT = DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT;
70 
71     // Settings override tracking for this instance
72     private String mSettingsKey;
73     private SettingsObserver mSettingsObserver;
74     private ContentResolver mResolver;
75     private final KeyValueListParser mParser = new KeyValueListParser(',');
76 
77     class SettingsObserver extends ContentObserver {
SettingsObserver(Handler handler)78         SettingsObserver(Handler handler) {
79             super(handler);
80         }
81 
82         @Override
onChange(boolean selfChange)83         public void onChange(boolean selfChange) {
84             updateConstants();
85         }
86     }
87 
88     // A given constants instance is configured to observe specific keys from which
89     // that instance's values are drawn.
BroadcastConstants(String settingsKey)90     public BroadcastConstants(String settingsKey) {
91         mSettingsKey = settingsKey;
92     }
93 
94     /**
95      * Spin up the observer lazily, since it can only happen once the settings provider
96      * has been brought into service
97      */
startObserving(Handler handler, ContentResolver resolver)98     public void startObserving(Handler handler, ContentResolver resolver) {
99         mResolver = resolver;
100 
101         mSettingsObserver = new SettingsObserver(handler);
102         mResolver.registerContentObserver(Settings.Global.getUriFor(mSettingsKey),
103                 false, mSettingsObserver);
104 
105         updateConstants();
106     }
107 
updateConstants()108     private void updateConstants() {
109         synchronized (mParser) {
110             try {
111                 mParser.setString(Settings.Global.getString(mResolver, mSettingsKey));
112             } catch (IllegalArgumentException e) {
113                 Slog.e(TAG, "Bad broadcast settings in key '" + mSettingsKey + "'", e);
114                 return;
115             }
116 
117             // Unspecified fields retain their current value rather than revert to default
118             TIMEOUT = mParser.getLong(KEY_TIMEOUT, TIMEOUT);
119             SLOW_TIME = mParser.getLong(KEY_SLOW_TIME, SLOW_TIME);
120             DEFERRAL = mParser.getLong(KEY_DEFERRAL, DEFERRAL);
121             DEFERRAL_DECAY_FACTOR = mParser.getFloat(KEY_DEFERRAL_DECAY_FACTOR,
122                     DEFERRAL_DECAY_FACTOR);
123             DEFERRAL_FLOOR = mParser.getLong(KEY_DEFERRAL_FLOOR, DEFERRAL_FLOOR);
124             ALLOW_BG_ACTIVITY_START_TIMEOUT = mParser.getLong(KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT,
125                     ALLOW_BG_ACTIVITY_START_TIMEOUT);
126         }
127     }
128 
129     /**
130      * Standard dumpsys support; invoked from BroadcastQueue dump
131      */
dump(PrintWriter pw)132     public void dump(PrintWriter pw) {
133         synchronized (mParser) {
134             pw.println();
135             pw.print("  Broadcast parameters (key=");
136             pw.print(mSettingsKey);
137             pw.print(", observing=");
138             pw.print(mSettingsObserver != null);
139             pw.println("):");
140 
141             pw.print("    "); pw.print(KEY_TIMEOUT); pw.print(" = ");
142             TimeUtils.formatDuration(TIMEOUT, pw);
143             pw.println();
144 
145             pw.print("    "); pw.print(KEY_SLOW_TIME); pw.print(" = ");
146             TimeUtils.formatDuration(SLOW_TIME, pw);
147             pw.println();
148 
149             pw.print("    "); pw.print(KEY_DEFERRAL); pw.print(" = ");
150             TimeUtils.formatDuration(DEFERRAL, pw);
151             pw.println();
152 
153             pw.print("    "); pw.print(KEY_DEFERRAL_DECAY_FACTOR); pw.print(" = ");
154             pw.println(DEFERRAL_DECAY_FACTOR);
155 
156             pw.print("    "); pw.print(KEY_DEFERRAL_FLOOR); pw.print(" = ");
157             TimeUtils.formatDuration(DEFERRAL_FLOOR, pw);
158 
159             pw.print("    "); pw.print(KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT); pw.print(" = ");
160             TimeUtils.formatDuration(ALLOW_BG_ACTIVITY_START_TIMEOUT, pw);
161             pw.println();
162         }
163     }
164 }
165