blob: c1677236fe7f9123de7226ca591db8aa25111f3b [file] [log] [blame]
Tony Mantlerc48ba6a2017-07-31 10:58:53 -07001/*
2 * Copyright (C) 2017 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.settingslib.development;
18
19import android.content.Context;
20import android.content.Intent;
21import android.os.SystemProperties;
22import android.support.annotation.VisibleForTesting;
23import android.support.v4.content.LocalBroadcastManager;
24import android.support.v7.preference.ListPreference;
25import android.support.v7.preference.Preference;
26import android.support.v7.preference.PreferenceScreen;
27
28import com.android.settingslib.R;
29import com.android.settingslib.core.AbstractPreferenceController;
30
31public abstract class AbstractLogdSizePreferenceController extends AbstractPreferenceController
32 implements Preference.OnPreferenceChangeListener {
33 public static final String ACTION_LOGD_SIZE_UPDATED = "com.android.settingslib.development."
34 + "AbstractLogdSizePreferenceController.LOGD_SIZE_UPDATED";
35 public static final String EXTRA_CURRENT_LOGD_VALUE = "CURRENT_LOGD_VALUE";
36
37 private static final String SELECT_LOGD_SIZE_KEY = "select_logd_size";
38 @VisibleForTesting
39 static final String SELECT_LOGD_SIZE_PROPERTY = "persist.logd.size";
40 static final String SELECT_LOGD_TAG_PROPERTY = "persist.log.tag";
41 // Tricky, isLoggable only checks for first character, assumes silence
42 static final String SELECT_LOGD_TAG_SILENCE = "Settings";
43 private static final String SELECT_LOGD_SNET_TAG_PROPERTY = "persist.log.tag.snet_event_log";
44 private static final String SELECT_LOGD_RUNTIME_SNET_TAG_PROPERTY = "log.tag.snet_event_log";
45 private static final String SELECT_LOGD_DEFAULT_SIZE_PROPERTY = "ro.logd.size";
46 @VisibleForTesting
47 static final String SELECT_LOGD_DEFAULT_SIZE_VALUE = "262144";
48 private static final String SELECT_LOGD_SVELTE_DEFAULT_SIZE_VALUE = "65536";
49 // 32768 is merely a menu marker, 64K is our lowest log buffer size we replace it with.
50 private static final String SELECT_LOGD_MINIMUM_SIZE_VALUE = "65536";
51 static final String SELECT_LOGD_OFF_SIZE_MARKER_VALUE = "32768";
52
53 private ListPreference mLogdSize;
54
55 public AbstractLogdSizePreferenceController(Context context) {
56 super(context);
57 }
58
59 @Override
60 public boolean isAvailable() {
61 return true;
62 }
63
64 @Override
65 public String getPreferenceKey() {
66 return SELECT_LOGD_SIZE_KEY;
67 }
68
69 @Override
70 public void displayPreference(PreferenceScreen screen) {
71 super.displayPreference(screen);
72 if (isAvailable()) {
73 mLogdSize = (ListPreference) screen.findPreference(SELECT_LOGD_SIZE_KEY);
74 }
75 }
76
77 @Override
78 public boolean onPreferenceChange(Preference preference, Object newValue) {
79 if (preference == mLogdSize) {
80 writeLogdSizeOption(newValue);
81 return true;
82 } else {
83 return false;
84 }
85 }
86
87 public void enablePreference(boolean enabled) {
88 if (isAvailable()) {
89 mLogdSize.setEnabled(enabled);
90 }
91 }
92
93 private String defaultLogdSizeValue() {
94 String defaultValue = SystemProperties.get(SELECT_LOGD_DEFAULT_SIZE_PROPERTY);
95 if ((defaultValue == null) || (defaultValue.length() == 0)) {
96 if (SystemProperties.get("ro.config.low_ram").equals("true")) {
97 defaultValue = SELECT_LOGD_SVELTE_DEFAULT_SIZE_VALUE;
98 } else {
99 defaultValue = SELECT_LOGD_DEFAULT_SIZE_VALUE;
100 }
101 }
102 return defaultValue;
103 }
104
105 public void updateLogdSizeValues() {
106 if (mLogdSize != null) {
107 String currentTag = SystemProperties.get(SELECT_LOGD_TAG_PROPERTY);
108 String currentValue = SystemProperties.get(SELECT_LOGD_SIZE_PROPERTY);
109 if ((currentTag != null) && currentTag.startsWith(SELECT_LOGD_TAG_SILENCE)) {
110 currentValue = SELECT_LOGD_OFF_SIZE_MARKER_VALUE;
111 }
112 LocalBroadcastManager.getInstance(mContext).sendBroadcastSync(
113 new Intent(ACTION_LOGD_SIZE_UPDATED)
114 .putExtra(EXTRA_CURRENT_LOGD_VALUE, currentValue));
115 if ((currentValue == null) || (currentValue.length() == 0)) {
116 currentValue = defaultLogdSizeValue();
117 }
118 String[] values = mContext.getResources()
119 .getStringArray(R.array.select_logd_size_values);
120 String[] titles = mContext.getResources()
121 .getStringArray(R.array.select_logd_size_titles);
122 int index = 2; // punt to second entry if not found
123 if (SystemProperties.get("ro.config.low_ram").equals("true")) {
124 mLogdSize.setEntries(R.array.select_logd_size_lowram_titles);
125 titles = mContext.getResources()
126 .getStringArray(R.array.select_logd_size_lowram_titles);
127 index = 1;
128 }
129 String[] summaries = mContext.getResources()
130 .getStringArray(R.array.select_logd_size_summaries);
131 for (int i = 0; i < titles.length; i++) {
132 if (currentValue.equals(values[i])
133 || currentValue.equals(titles[i])) {
134 index = i;
135 break;
136 }
137 }
138 mLogdSize.setValue(values[index]);
139 mLogdSize.setSummary(summaries[index]);
140 }
141 }
142
143 public void writeLogdSizeOption(Object newValue) {
144 boolean disable = (newValue != null) &&
145 (newValue.toString().equals(SELECT_LOGD_OFF_SIZE_MARKER_VALUE));
146 String currentTag = SystemProperties.get(SELECT_LOGD_TAG_PROPERTY);
147 if (currentTag == null) {
148 currentTag = "";
149 }
150 // filter clean and unstack all references to our setting
151 String newTag = currentTag.replaceAll(
152 ",+" + SELECT_LOGD_TAG_SILENCE, "").replaceFirst(
153 "^" + SELECT_LOGD_TAG_SILENCE + ",*", "").replaceAll(
154 ",+", ",").replaceFirst(
155 ",+$", "");
156 if (disable) {
157 newValue = SELECT_LOGD_MINIMUM_SIZE_VALUE;
158 // Make sure snet_event_log get through first, but do not override
159 String snetValue = SystemProperties.get(SELECT_LOGD_SNET_TAG_PROPERTY);
160 if ((snetValue == null) || (snetValue.length() == 0)) {
161 snetValue = SystemProperties.get(SELECT_LOGD_RUNTIME_SNET_TAG_PROPERTY);
162 if ((snetValue == null) || (snetValue.length() == 0)) {
163 SystemProperties.set(SELECT_LOGD_SNET_TAG_PROPERTY, "I");
164 }
165 }
166 // Silence all log sources, security logs notwithstanding
167 if (newTag.length() != 0) {
168 newTag = "," + newTag;
169 }
170 // Stack settings, stack to help preserve original value
171 newTag = SELECT_LOGD_TAG_SILENCE + newTag;
172 }
173 if (!newTag.equals(currentTag)) {
174 SystemProperties.set(SELECT_LOGD_TAG_PROPERTY, newTag);
175 }
176 String defaultValue = defaultLogdSizeValue();
177 final String size = ((newValue != null) && (newValue.toString().length() != 0)) ?
178 newValue.toString() : defaultValue;
179 SystemProperties.set(SELECT_LOGD_SIZE_PROPERTY, defaultValue.equals(size) ? "" : size);
180 SystemProperties.set("ctl.start", "logd-reinit");
181 SystemPropPoker.getInstance().poke();
182 updateLogdSizeValues();
183 }
184}