Loading core/java/android/telephony/DropBoxManagerLoggerBackend.java 0 → 100644 +261 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.os.DropBoxManager; import android.os.Handler; import android.os.HandlerThread; import android.util.Log; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Optional; /** * A persistent logger backend that stores logs in Android DropBoxManager * * @hide */ public class DropBoxManagerLoggerBackend implements PersistentLoggerBackend { private static final String TAG = "DropBoxManagerLoggerBackend"; // Separate tag reference to be explicitly used for dropboxmanager instead of logcat logging private static final String DROPBOX_TAG = "DropBoxManagerLoggerBackend"; private static final DateTimeFormatter LOG_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern("MM-dd HH:mm:ss.SSS"); private static final ZoneId LOCAL_ZONE_ID = ZoneId.systemDefault(); private static final int BUFFER_SIZE_BYTES = 500 * 1024; // 500 KB private static final int MIN_BUFFER_BYTES_FOR_FLUSH = 5 * 1024; // 5 KB private static DropBoxManagerLoggerBackend sInstance; private final DropBoxManager mDropBoxManager; private final Object mBufferLock = new Object(); @GuardedBy("mBufferLock") private final StringBuilder mLogBuffer = new StringBuilder(); private long mBufferStartTime = -1L; private final HandlerThread mHandlerThread = new HandlerThread(DROPBOX_TAG); private final Handler mHandler; // Flag for determining if logging is enabled as a general feature private final boolean mDropBoxManagerLoggingEnabled; // Flag for controlling if logging is enabled at runtime private boolean mIsLoggingEnabled = false; /** * Returns a singleton instance of {@code DropBoxManagerLoggerBackend} that will log to * DropBoxManager if the config_dropboxmanager_persistent_logging_enabled resource config is * enabled. * @param context Android context */ @Nullable public static synchronized DropBoxManagerLoggerBackend getInstance(@NonNull Context context) { if (sInstance == null) { sInstance = new DropBoxManagerLoggerBackend(context); } return sInstance; } private DropBoxManagerLoggerBackend(@NonNull Context context) { mDropBoxManager = context.getSystemService(DropBoxManager.class); mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mDropBoxManagerLoggingEnabled = persistentLoggingEnabled(context); } private boolean persistentLoggingEnabled(@NonNull Context context) { try { return context.getResources().getBoolean( R.bool.config_dropboxmanager_persistent_logging_enabled); } catch (RuntimeException e) { Log.w(TAG, "Persistent logging config not found"); return false; } } /** * Enable or disable logging to DropBoxManager * @param isLoggingEnabled Whether logging should be enabled */ public void setLoggingEnabled(boolean isLoggingEnabled) { Log.i(DROPBOX_TAG, "toggle logging: " + isLoggingEnabled); mIsLoggingEnabled = isLoggingEnabled; } /** * Persist a DEBUG log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void debug(@NonNull String tag, @NonNull String msg) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("D", tag, msg, Optional.empty()); } /** * Persist a INFO log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void info(@NonNull String tag, @NonNull String msg) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("I", tag, msg, Optional.empty()); } /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void warn(@NonNull String tag, @NonNull String msg) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("W", tag, msg, Optional.empty()); } /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ public void warn(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("W", tag, msg, Optional.of(t)); } /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void error(@NonNull String tag, @NonNull String msg) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("E", tag, msg, Optional.empty()); } /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ public void error(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("E", tag, msg, Optional.of(t)); } private synchronized void bufferLog( @NonNull String level, @NonNull String tag, @NonNull String msg, Optional<Throwable> t) { if (!mIsLoggingEnabled) { return; } if (mBufferStartTime == -1L) { mBufferStartTime = System.currentTimeMillis(); } synchronized (mBufferLock) { mLogBuffer .append(formatLog(level, tag, msg, t)) .append("\n"); if (mLogBuffer.length() >= BUFFER_SIZE_BYTES) { flushAsync(); } } } private String formatLog( @NonNull String level, @NonNull String tag, @NonNull String msg, Optional<Throwable> t) { // Expected format = "$Timestamp $Level $Tag: $Message" return formatTimestamp(System.currentTimeMillis()) + " " + level + " " + tag + ": " + t.map(throwable -> msg + ": " + Log.getStackTraceString(throwable)).orElse(msg); } private String formatTimestamp(long currentTimeMillis) { return Instant.ofEpochMilli(currentTimeMillis) .atZone(LOCAL_ZONE_ID) .format(LOG_TIMESTAMP_FORMATTER); } /** * Flushes all buffered logs into DropBoxManager as a single log record with a tag of * {@link #DROPBOX_TAG} asynchronously. Should be invoked sparingly as DropBoxManager has * device-level limitations on the number files that can be stored. */ public void flushAsync() { if (!mDropBoxManagerLoggingEnabled) { return; } mHandler.post(this::flush); }; /** * Flushes all buffered logs into DropBoxManager as a single log record with a tag of * {@link #DROPBOX_TAG}. Should be invoked sparingly as DropBoxManager has device-level * limitations on the number files that can be stored. */ public void flush() { if (!mDropBoxManagerLoggingEnabled) { return; } synchronized (mBufferLock) { if (mLogBuffer.length() < MIN_BUFFER_BYTES_FOR_FLUSH) { return; } Log.d(DROPBOX_TAG, "Flushing logs from " + formatTimestamp(mBufferStartTime) + " to " + formatTimestamp(System.currentTimeMillis())); try { mDropBoxManager.addText(DROPBOX_TAG, mLogBuffer.toString()); } catch (Exception e) { Log.w(DROPBOX_TAG, "Failed to flush logs of length " + mLogBuffer.length() + " to DropBoxManager", e); } mLogBuffer.setLength(0); } mBufferStartTime = -1L; } } core/java/android/telephony/PersistentLogger.java 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony; import android.annotation.NonNull; /** * A persistent logging client. Intended for persisting SOS/emergency related critical debug logs * in situations where standard Android logcat logs may not be retained long enough or available * for access. * * @hide */ public class PersistentLogger { private final PersistentLoggerBackend mPersistentLoggerBackend; public PersistentLogger(@NonNull PersistentLoggerBackend persistentLoggerBackend) { mPersistentLoggerBackend = persistentLoggerBackend; } /** * Persist a DEBUG log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void debug(@NonNull String tag, @NonNull String msg) { mPersistentLoggerBackend.debug(tag, msg); } /** * Persist a INFO log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void info(@NonNull String tag, @NonNull String msg) { mPersistentLoggerBackend.info(tag, msg); } /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void warn(@NonNull String tag, @NonNull String msg) { mPersistentLoggerBackend.warn(tag, msg); } /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ public void warn(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) { mPersistentLoggerBackend.warn(tag, msg, t); } /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void error(@NonNull String tag, @NonNull String msg) { mPersistentLoggerBackend.error(tag, msg); } /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ public void error(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) { mPersistentLoggerBackend.error(tag, msg, t); } } core/java/android/telephony/PersistentLoggerBackend.java 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony; import android.annotation.NonNull; /** * Interface for logging backends to provide persistent log storage. * * @hide */ public interface PersistentLoggerBackend { /** * Persist a DEBUG log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ void debug(@NonNull String tag, @NonNull String msg); /** * Persist a INFO log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ void info(@NonNull String tag, @NonNull String msg); /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ void warn(@NonNull String tag, @NonNull String msg); /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ void warn(@NonNull String tag, @NonNull String msg, @NonNull Throwable t); /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ void error(@NonNull String tag, @NonNull String msg); /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ void error(@NonNull String tag, @NonNull String msg, @NonNull Throwable t); } core/res/res/values/config_telephony.xml +5 −0 Original line number Diff line number Diff line Loading @@ -392,4 +392,9 @@ <integer name="config_wait_for_datagram_sending_response_for_last_message_timeout_millis">60000</integer> <java-symbol type="integer" name="config_wait_for_datagram_sending_response_for_last_message_timeout_millis" /> <!-- Boolean indicating whether to enable persistent logging via DropBoxManager. Used in persisting SOS/emergency related log messages. --> <bool name="config_dropboxmanager_persistent_logging_enabled">false</bool> <java-symbol type="bool" name="config_dropboxmanager_persistent_logging_enabled" /> </resources> Loading
core/java/android/telephony/DropBoxManagerLoggerBackend.java 0 → 100644 +261 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.os.DropBoxManager; import android.os.Handler; import android.os.HandlerThread; import android.util.Log; import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import java.time.Instant; import java.time.ZoneId; import java.time.format.DateTimeFormatter; import java.util.Optional; /** * A persistent logger backend that stores logs in Android DropBoxManager * * @hide */ public class DropBoxManagerLoggerBackend implements PersistentLoggerBackend { private static final String TAG = "DropBoxManagerLoggerBackend"; // Separate tag reference to be explicitly used for dropboxmanager instead of logcat logging private static final String DROPBOX_TAG = "DropBoxManagerLoggerBackend"; private static final DateTimeFormatter LOG_TIMESTAMP_FORMATTER = DateTimeFormatter.ofPattern("MM-dd HH:mm:ss.SSS"); private static final ZoneId LOCAL_ZONE_ID = ZoneId.systemDefault(); private static final int BUFFER_SIZE_BYTES = 500 * 1024; // 500 KB private static final int MIN_BUFFER_BYTES_FOR_FLUSH = 5 * 1024; // 5 KB private static DropBoxManagerLoggerBackend sInstance; private final DropBoxManager mDropBoxManager; private final Object mBufferLock = new Object(); @GuardedBy("mBufferLock") private final StringBuilder mLogBuffer = new StringBuilder(); private long mBufferStartTime = -1L; private final HandlerThread mHandlerThread = new HandlerThread(DROPBOX_TAG); private final Handler mHandler; // Flag for determining if logging is enabled as a general feature private final boolean mDropBoxManagerLoggingEnabled; // Flag for controlling if logging is enabled at runtime private boolean mIsLoggingEnabled = false; /** * Returns a singleton instance of {@code DropBoxManagerLoggerBackend} that will log to * DropBoxManager if the config_dropboxmanager_persistent_logging_enabled resource config is * enabled. * @param context Android context */ @Nullable public static synchronized DropBoxManagerLoggerBackend getInstance(@NonNull Context context) { if (sInstance == null) { sInstance = new DropBoxManagerLoggerBackend(context); } return sInstance; } private DropBoxManagerLoggerBackend(@NonNull Context context) { mDropBoxManager = context.getSystemService(DropBoxManager.class); mHandlerThread.start(); mHandler = new Handler(mHandlerThread.getLooper()); mDropBoxManagerLoggingEnabled = persistentLoggingEnabled(context); } private boolean persistentLoggingEnabled(@NonNull Context context) { try { return context.getResources().getBoolean( R.bool.config_dropboxmanager_persistent_logging_enabled); } catch (RuntimeException e) { Log.w(TAG, "Persistent logging config not found"); return false; } } /** * Enable or disable logging to DropBoxManager * @param isLoggingEnabled Whether logging should be enabled */ public void setLoggingEnabled(boolean isLoggingEnabled) { Log.i(DROPBOX_TAG, "toggle logging: " + isLoggingEnabled); mIsLoggingEnabled = isLoggingEnabled; } /** * Persist a DEBUG log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void debug(@NonNull String tag, @NonNull String msg) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("D", tag, msg, Optional.empty()); } /** * Persist a INFO log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void info(@NonNull String tag, @NonNull String msg) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("I", tag, msg, Optional.empty()); } /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void warn(@NonNull String tag, @NonNull String msg) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("W", tag, msg, Optional.empty()); } /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ public void warn(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("W", tag, msg, Optional.of(t)); } /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void error(@NonNull String tag, @NonNull String msg) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("E", tag, msg, Optional.empty()); } /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ public void error(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) { if (!mDropBoxManagerLoggingEnabled) { return; } bufferLog("E", tag, msg, Optional.of(t)); } private synchronized void bufferLog( @NonNull String level, @NonNull String tag, @NonNull String msg, Optional<Throwable> t) { if (!mIsLoggingEnabled) { return; } if (mBufferStartTime == -1L) { mBufferStartTime = System.currentTimeMillis(); } synchronized (mBufferLock) { mLogBuffer .append(formatLog(level, tag, msg, t)) .append("\n"); if (mLogBuffer.length() >= BUFFER_SIZE_BYTES) { flushAsync(); } } } private String formatLog( @NonNull String level, @NonNull String tag, @NonNull String msg, Optional<Throwable> t) { // Expected format = "$Timestamp $Level $Tag: $Message" return formatTimestamp(System.currentTimeMillis()) + " " + level + " " + tag + ": " + t.map(throwable -> msg + ": " + Log.getStackTraceString(throwable)).orElse(msg); } private String formatTimestamp(long currentTimeMillis) { return Instant.ofEpochMilli(currentTimeMillis) .atZone(LOCAL_ZONE_ID) .format(LOG_TIMESTAMP_FORMATTER); } /** * Flushes all buffered logs into DropBoxManager as a single log record with a tag of * {@link #DROPBOX_TAG} asynchronously. Should be invoked sparingly as DropBoxManager has * device-level limitations on the number files that can be stored. */ public void flushAsync() { if (!mDropBoxManagerLoggingEnabled) { return; } mHandler.post(this::flush); }; /** * Flushes all buffered logs into DropBoxManager as a single log record with a tag of * {@link #DROPBOX_TAG}. Should be invoked sparingly as DropBoxManager has device-level * limitations on the number files that can be stored. */ public void flush() { if (!mDropBoxManagerLoggingEnabled) { return; } synchronized (mBufferLock) { if (mLogBuffer.length() < MIN_BUFFER_BYTES_FOR_FLUSH) { return; } Log.d(DROPBOX_TAG, "Flushing logs from " + formatTimestamp(mBufferStartTime) + " to " + formatTimestamp(System.currentTimeMillis())); try { mDropBoxManager.addText(DROPBOX_TAG, mLogBuffer.toString()); } catch (Exception e) { Log.w(DROPBOX_TAG, "Failed to flush logs of length " + mLogBuffer.length() + " to DropBoxManager", e); } mLogBuffer.setLength(0); } mBufferStartTime = -1L; } }
core/java/android/telephony/PersistentLogger.java 0 → 100644 +90 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony; import android.annotation.NonNull; /** * A persistent logging client. Intended for persisting SOS/emergency related critical debug logs * in situations where standard Android logcat logs may not be retained long enough or available * for access. * * @hide */ public class PersistentLogger { private final PersistentLoggerBackend mPersistentLoggerBackend; public PersistentLogger(@NonNull PersistentLoggerBackend persistentLoggerBackend) { mPersistentLoggerBackend = persistentLoggerBackend; } /** * Persist a DEBUG log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void debug(@NonNull String tag, @NonNull String msg) { mPersistentLoggerBackend.debug(tag, msg); } /** * Persist a INFO log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void info(@NonNull String tag, @NonNull String msg) { mPersistentLoggerBackend.info(tag, msg); } /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void warn(@NonNull String tag, @NonNull String msg) { mPersistentLoggerBackend.warn(tag, msg); } /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ public void warn(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) { mPersistentLoggerBackend.warn(tag, msg, t); } /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ public void error(@NonNull String tag, @NonNull String msg) { mPersistentLoggerBackend.error(tag, msg); } /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ public void error(@NonNull String tag, @NonNull String msg, @NonNull Throwable t) { mPersistentLoggerBackend.error(tag, msg, t); } }
core/java/android/telephony/PersistentLoggerBackend.java 0 → 100644 +71 −0 Original line number Diff line number Diff line /* * Copyright (C) 2024 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.telephony; import android.annotation.NonNull; /** * Interface for logging backends to provide persistent log storage. * * @hide */ public interface PersistentLoggerBackend { /** * Persist a DEBUG log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ void debug(@NonNull String tag, @NonNull String msg); /** * Persist a INFO log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ void info(@NonNull String tag, @NonNull String msg); /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ void warn(@NonNull String tag, @NonNull String msg); /** * Persist a WARN log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ void warn(@NonNull String tag, @NonNull String msg, @NonNull Throwable t); /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. */ void error(@NonNull String tag, @NonNull String msg); /** * Persist a ERROR log message. * @param tag Used to identify the source of a log message. * @param msg The message you would like logged. * @param t An exception to log. */ void error(@NonNull String tag, @NonNull String msg, @NonNull Throwable t); }
core/res/res/values/config_telephony.xml +5 −0 Original line number Diff line number Diff line Loading @@ -392,4 +392,9 @@ <integer name="config_wait_for_datagram_sending_response_for_last_message_timeout_millis">60000</integer> <java-symbol type="integer" name="config_wait_for_datagram_sending_response_for_last_message_timeout_millis" /> <!-- Boolean indicating whether to enable persistent logging via DropBoxManager. Used in persisting SOS/emergency related log messages. --> <bool name="config_dropboxmanager_persistent_logging_enabled">false</bool> <java-symbol type="bool" name="config_dropboxmanager_persistent_logging_enabled" /> </resources>