Messaging: Remove GServices
We don't have an actual implementation returning anything but the defaults, so apply the defaults directly anywhere we need them Change-Id: Ic651b4b13977799f2f4d2c702c430798fbff77f8
This commit is contained in:
@@ -40,27 +40,12 @@ public final class Assert {
|
||||
sShouldCrash = sIsEngBuild = true;
|
||||
}
|
||||
|
||||
private static void refreshGservices(final BugleGservices gservices) {
|
||||
sShouldCrash = sIsEngBuild;
|
||||
if (!sShouldCrash) {
|
||||
sShouldCrash = gservices.getBoolean(
|
||||
BugleGservicesKeys.ASSERTS_FATAL,
|
||||
BugleGservicesKeys.ASSERTS_FATAL_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
// Static initializer block to find out if we're running an eng or
|
||||
// release build.
|
||||
static {
|
||||
setIfEngBuild();
|
||||
}
|
||||
|
||||
// This is called from FactoryImpl once the Gservices class is initialized.
|
||||
public static void initializeGservices (final BugleGservices gservices) {
|
||||
gservices.registerForChanges(() -> refreshGservices(gservices));
|
||||
refreshGservices(gservices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Halt execution if this is not an eng build.
|
||||
* <p>Intended for use in code paths that should be run only for tests and never on
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 com.android.messaging.util;
|
||||
|
||||
import com.android.messaging.Factory;
|
||||
|
||||
/**
|
||||
* A thin wrapper for getting GServices value. During constructor time a one time background thread
|
||||
* will cache all GServices key with the prefix of "bugle_". All get calls will wait for Gservices
|
||||
* to finish caching the first time. In practice, the background thread will finish before any get
|
||||
* request.
|
||||
*/
|
||||
public abstract class BugleGservices {
|
||||
static final String BUGLE_GSERVICES_PREFIX = "bugle_";
|
||||
|
||||
public static BugleGservices get() {
|
||||
return Factory.get().getBugleGservices();
|
||||
}
|
||||
|
||||
public abstract void registerForChanges(final Runnable r);
|
||||
|
||||
/**
|
||||
* @param key The key to look up in GServices
|
||||
* @param defaultValue The default value if value in GServices is null or if
|
||||
* NumberFormatException is caught.
|
||||
* @return The corresponding value, or the default value.
|
||||
*/
|
||||
public abstract long getLong(final String key, final long defaultValue);
|
||||
|
||||
/**
|
||||
* @param key The key to look up in GServices
|
||||
* @param defaultValue The default value if value in GServices is null or if
|
||||
* NumberFormatException is caught.
|
||||
* @return The corresponding value, or the default value.
|
||||
*/
|
||||
public abstract int getInt(final String key, final int defaultValue);
|
||||
|
||||
/**
|
||||
* @param key The key to look up in GServices
|
||||
* @param defaultValue The default value if value in GServices is null.
|
||||
* @return The corresponding value, or the default value.
|
||||
*/
|
||||
public abstract boolean getBoolean(final String key, final boolean defaultValue);
|
||||
|
||||
/**
|
||||
* @param key The key to look up in GServices
|
||||
* @param defaultValue The default value if value in GServices is null.
|
||||
* @return The corresponding value, or the default value.
|
||||
*/
|
||||
public abstract String getString(final String key, final String defaultValue);
|
||||
|
||||
/**
|
||||
* @param key The key to look up in GServices
|
||||
* @param defaultValue The default value if value in GServices is null.
|
||||
* @return The corresponding value, or the default value.
|
||||
*/
|
||||
public abstract float getFloat(final String key, final float defaultValue);
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 com.android.messaging.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* A thin wrapper for getting GServices value.
|
||||
*/
|
||||
public class BugleGservicesImpl extends BugleGservices {
|
||||
public BugleGservicesImpl(final Context context) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerForChanges(final Runnable r) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the key has the expected prefix.
|
||||
*/
|
||||
private void assertKeyAndWaitForGservices(final String key) {
|
||||
Assert.isTrue(key.startsWith(BUGLE_GSERVICES_PREFIX));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getLong(final String key, final long defaultValue) {
|
||||
assertKeyAndWaitForGservices(key);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt(final String key, final int defaultValue) {
|
||||
assertKeyAndWaitForGservices(key);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBoolean(final String key, final boolean defaultValue) {
|
||||
assertKeyAndWaitForGservices(key);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString(final String key, final String defaultValue) {
|
||||
assertKeyAndWaitForGservices(key);
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat(final String key, final float defaultValue) {
|
||||
assertKeyAndWaitForGservices(key);
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
@@ -24,49 +24,29 @@ package com.android.messaging.util;
|
||||
public final class BugleGservicesKeys {
|
||||
private BugleGservicesKeys() {} // do not instantiate
|
||||
|
||||
/**
|
||||
* Whether to enable extra debugging features on the client. Default is
|
||||
* {@value #ENABLE_DEBUGGING_FEATURES_DEFAULT}.
|
||||
*/
|
||||
public static final String ENABLE_DEBUGGING_FEATURES
|
||||
= "bugle_debugging";
|
||||
public static final boolean ENABLE_DEBUGGING_FEATURES_DEFAULT
|
||||
= false;
|
||||
|
||||
/**
|
||||
* Whether to enable saving extra logs. Default is {@value #ENABLE_LOG_SAVER_DEFAULT}.
|
||||
*/
|
||||
public static final String ENABLE_LOG_SAVER = "bugle_logsaver";
|
||||
public static final boolean ENABLE_LOG_SAVER_DEFAULT = false;
|
||||
|
||||
/**
|
||||
* Time in milliseconds of initial (attempt 1) resend backoff for failing messages
|
||||
*/
|
||||
public static final String INITIAL_MESSAGE_RESEND_DELAY_MS = "bugle_resend_delay_in_millis";
|
||||
public static final long INITIAL_MESSAGE_RESEND_DELAY_MS_DEFAULT = 5 * 1000L;
|
||||
|
||||
/**
|
||||
* Time in milliseconds of max resend backoff for failing messages
|
||||
*/
|
||||
public static final String MAX_MESSAGE_RESEND_DELAY_MS = "bugle_max_resend_delay_in_millis";
|
||||
public static final long MAX_MESSAGE_RESEND_DELAY_MS_DEFAULT = 2 * 60 * 60 * 1000L;
|
||||
|
||||
/**
|
||||
* Time in milliseconds of resend window for unsent messages
|
||||
*/
|
||||
public static final String MESSAGE_RESEND_TIMEOUT_MS = "bugle_resend_timeout_in_millis";
|
||||
public static final long MESSAGE_RESEND_TIMEOUT_MS_DEFAULT = 20 * 60 * 1000L;
|
||||
|
||||
/**
|
||||
* Time in milliseconds of download window for new mms notifications
|
||||
*/
|
||||
public static final String MESSAGE_DOWNLOAD_TIMEOUT_MS = "bugle_download_timeout_in_millis";
|
||||
public static final long MESSAGE_DOWNLOAD_TIMEOUT_MS_DEFAULT = 20 * 60 * 1000L;
|
||||
|
||||
/**
|
||||
* Time in milliseconds for SMS send timeout
|
||||
*/
|
||||
public static final String SMS_SEND_TIMEOUT_IN_MILLIS = "bugle_sms_send_timeout";
|
||||
public static final long SMS_SEND_TIMEOUT_IN_MILLIS_DEFAULT = 5 * 60 * 1000L;
|
||||
|
||||
/**
|
||||
@@ -87,17 +67,9 @@ public final class BugleGservicesKeys {
|
||||
* whatever reasons. Keeping this low ensures responsiveness of the application.
|
||||
* 4. The limit on number of total messages to scan in one batch.
|
||||
*/
|
||||
public static final String SMS_SYNC_BATCH_SIZE_MIN =
|
||||
"bugle_sms_sync_batch_size_min";
|
||||
public static final int SMS_SYNC_BATCH_SIZE_MIN_DEFAULT = 80;
|
||||
public static final String SMS_SYNC_BATCH_SIZE_MAX =
|
||||
"bugle_sms_sync_batch_size_max";
|
||||
public static final int SMS_SYNC_BATCH_SIZE_MAX_DEFAULT = 1000;
|
||||
public static final String SMS_SYNC_BATCH_TIME_LIMIT_MILLIS =
|
||||
"bugle_sms_sync_batch_time_limit";
|
||||
public static final long SMS_SYNC_BATCH_TIME_LIMIT_MILLIS_DEFAULT = 400;
|
||||
public static final String SMS_SYNC_BATCH_MAX_MESSAGES_TO_SCAN =
|
||||
"bugle_sms_sync_batch_max_messages_to_scan";
|
||||
public static final int SMS_SYNC_BATCH_MAX_MESSAGES_TO_SCAN_DEFAULT =
|
||||
SMS_SYNC_BATCH_SIZE_MAX_DEFAULT * 4;
|
||||
|
||||
@@ -108,18 +80,13 @@ public final class BugleGservicesKeys {
|
||||
* when bringing in changes made outside the application. It also represents a buffer
|
||||
* to ensure that sync doesn't trigger based on changes made within the application.
|
||||
*/
|
||||
public static final String SMS_SYNC_BACKOFF_TIME_MILLIS =
|
||||
"bugle_sms_sync_backoff_time";
|
||||
public static final long SMS_SYNC_BACKOFF_TIME_MILLIS_DEFAULT = 5000L;
|
||||
|
||||
/**
|
||||
* Just in case if we fall into a loop of full sync -> still not synchronized -> full sync ...
|
||||
* This forces a backoff time so that we at most do full sync once a while (an hour by default)
|
||||
*/
|
||||
public static final String SMS_FULL_SYNC_BACKOFF_TIME_MILLIS =
|
||||
"bugle_sms_full_sync_backoff_time";
|
||||
public static final long SMS_FULL_SYNC_BACKOFF_TIME_MILLIS_DEFAULT = 60 * 60 * 1000;
|
||||
|
||||
/**
|
||||
* MMS UA profile url.
|
||||
*
|
||||
@@ -127,66 +94,30 @@ public final class BugleGservicesKeys {
|
||||
* latest and greatest phones. However, if we're on KitKat or below we can't get the phone's
|
||||
* UA profile and thus we need to send them the default url.
|
||||
*/
|
||||
public static final String MMS_UA_PROFILE_URL =
|
||||
"bugle_mms_uaprofurl";
|
||||
public static final String MMS_UA_PROFILE_URL_DEFAULT =
|
||||
"http://www.gstatic.com/android/sms/mms_ua_profile.xml";
|
||||
|
||||
/**
|
||||
* MMS apn mmsc
|
||||
*/
|
||||
public static final String MMS_MMSC =
|
||||
"bugle_mms_mmsc";
|
||||
|
||||
/**
|
||||
* MMS apn proxy ip address
|
||||
*/
|
||||
public static final String MMS_PROXY_ADDRESS =
|
||||
"bugle_mms_proxy_address";
|
||||
|
||||
/**
|
||||
* MMS apn proxy port
|
||||
*/
|
||||
public static final String MMS_PROXY_PORT =
|
||||
"bugle_mms_proxy_port";
|
||||
|
||||
/**
|
||||
* List of known SMS system messages that we will ignore (no deliver, no abort) so that the
|
||||
* user doesn't see them and the appropriate app is able to handle them. We are delivering
|
||||
* these as a \n delimited list of patterns, however we should eventually move to storing
|
||||
* them with the per-carrier mms config xml file.
|
||||
*/
|
||||
public static final String SMS_IGNORE_MESSAGE_REGEX =
|
||||
"bugle_sms_ignore_message_regex";
|
||||
public static final String SMS_IGNORE_MESSAGE_REGEX_DEFAULT = "";
|
||||
|
||||
/**
|
||||
* When receiving or importing an mms, limit the length of text to this limit. Huge blocks
|
||||
* of text can cause the app to hang/ANR/or crash in native text code..
|
||||
*/
|
||||
public static final String MMS_TEXT_LIMIT = "bugle_mms_text_limit";
|
||||
public static final int MMS_TEXT_LIMIT_DEFAULT = 2000;
|
||||
|
||||
/**
|
||||
* Max number of attachments the user may add to a single message.
|
||||
*/
|
||||
public static final String MMS_ATTACHMENT_LIMIT = "bugle_mms_attachment_limit";
|
||||
public static final int MMS_ATTACHMENT_LIMIT_DEFAULT = 10;
|
||||
|
||||
/**
|
||||
* The max number of messages to show in a single conversation notification. We always show
|
||||
* the most recent message. If this value is >1, we may also include prior messages as well.
|
||||
*/
|
||||
public static final String MAX_MESSAGES_IN_CONVERSATION_NOTIFICATION =
|
||||
"bugle_max_messages_in_conversation_notification";
|
||||
public static final int MAX_MESSAGES_IN_CONVERSATION_NOTIFICATION_DEFAULT = 7;
|
||||
|
||||
/**
|
||||
* Time (in seconds) between notification ringing for incoming messages of the same
|
||||
* conversation. We won't ding more often than this value for messages coming in at a high rate.
|
||||
*/
|
||||
public static final String NOTIFICATION_TIME_BETWEEN_RINGS_SECONDS
|
||||
= "bugle_notification_time_between_rings_seconds";
|
||||
public static final int NOTIFICATION_TIME_BETWEEN_RINGS_SECONDS_DEFAULT = 10;
|
||||
|
||||
/**
|
||||
@@ -195,91 +126,11 @@ public final class BugleGservicesKeys {
|
||||
* less screen real estate, so we may want to optimize for that case. Note that if a wearable
|
||||
* is paired, this value will apply to notifications as shown both on the watch and the phone.
|
||||
*/
|
||||
public static final String MAX_MESSAGES_IN_CONVERSATION_NOTIFICATION_WITH_WEARABLE =
|
||||
"bugle_max_messages_in_conversation_notification_with_wearable";
|
||||
public static final int MAX_MESSAGES_IN_CONVERSATION_NOTIFICATION_WITH_WEARABLE_DEFAULT = 1;
|
||||
|
||||
/**
|
||||
* Regular expression to match against query. If it matches then display
|
||||
* the query plan for this query.
|
||||
*/
|
||||
public static final String EXPLAIN_QUERY_PLAN_REGEXP = "bugle_query_plan_regexp";
|
||||
|
||||
/**
|
||||
* Whether asserts are fatal on user/userdebug builds.
|
||||
* Default is {@value #ASSERTS_FATAL_DEFAULT}.
|
||||
*/
|
||||
public static final String ASSERTS_FATAL = "bugle_asserts_fatal";
|
||||
public static final boolean ASSERTS_FATAL_DEFAULT = false;
|
||||
|
||||
/**
|
||||
* Whether to use API for sending/downloading MMS (if present, true for L).
|
||||
* Default is {@value #USE_MMS_API_IF_PRESENT_DEFAULT}.
|
||||
*/
|
||||
public static final String USE_MMS_API_IF_PRESENT = "bugle_use_mms_api";
|
||||
public static final boolean USE_MMS_API_IF_PRESENT_DEFAULT = true;
|
||||
|
||||
/**
|
||||
* Whether to always auto-complete email addresses for sending MMS. By default, Bugle starts
|
||||
* to auto-complete after the user has typed the "@" character.
|
||||
* Default is (@value ALWAYS_AUTOCOMPLETE_EMAIL_ADDRESS_DEFAULT}.
|
||||
*/
|
||||
public static final String ALWAYS_AUTOCOMPLETE_EMAIL_ADDRESS =
|
||||
"bugle_always_autocomplete_email_address";
|
||||
public static final boolean ALWAYS_AUTOCOMPLETE_EMAIL_ADDRESS_DEFAULT = false;
|
||||
|
||||
// We typically request an aspect ratio close the the screen size, but some cameras can be
|
||||
// flaky and not work well in certain aspect ratios. This allows us to guide the CameraManager
|
||||
// to pick a more reliable aspect ratio. The value is a float like 1.333f or 1.777f. There is
|
||||
// no hard coded default because the default is the screen aspect ratio.
|
||||
public static final String CAMERA_ASPECT_RATIO = "bugle_camera_aspect_ratio";
|
||||
|
||||
/**
|
||||
* The recent time range within which we should check MMS WAP Push duplication
|
||||
* If the value is 0, it signals that we should use old dedup algorithm for wap push
|
||||
*/
|
||||
public static final String MMS_WAP_PUSH_DEDUP_TIME_LIMIT_SECS =
|
||||
"bugle_mms_wap_push_dedup_time_limit_secs";
|
||||
public static final long MMS_WAP_PUSH_DEDUP_TIME_LIMIT_SECS_DEFAULT = 7 * 24 * 3600; // 7 days
|
||||
|
||||
/**
|
||||
* Whether to use persistent, on-disk LogSaver
|
||||
*/
|
||||
public static final String PERSISTENT_LOGSAVER = "bugle_persistent_logsaver";
|
||||
public static final boolean PERSISTENT_LOGSAVER_DEFAULT = false;
|
||||
|
||||
/**
|
||||
* For in-memory LogSaver, what's the size of memory buffer in number of records
|
||||
*/
|
||||
public static final String IN_MEMORY_LOGSAVER_RECORD_COUNT =
|
||||
"bugle_in_memory_logsaver_record_count";
|
||||
public static final int IN_MEMORY_LOGSAVER_RECORD_COUNT_DEFAULT = 500;
|
||||
|
||||
/**
|
||||
* For on-disk LogSaver, what's the size of file rotation set
|
||||
*/
|
||||
public static final String PERSISTENT_LOGSAVER_ROTATION_SET_SIZE =
|
||||
"bugle_persistent_logsaver_rotation_set_size";
|
||||
public static final int PERSISTENT_LOGSAVER_ROTATION_SET_SIZE_DEFAULT = 8;
|
||||
|
||||
/**
|
||||
* For on-disk LogSaver, what's the byte limit of a single log file
|
||||
*/
|
||||
public static final String PERSISTENT_LOGSAVER_FILE_LIMIT_BYTES =
|
||||
"bugle_persistent_logsaver_file_limit";
|
||||
public static final int PERSISTENT_LOGSAVER_FILE_LIMIT_BYTES_DEFAULT = 256 * 1024; // 256KB
|
||||
|
||||
/**
|
||||
* We concatenate all text parts in an MMS to form the message text. This specifies
|
||||
* the separator between the combinated text parts. Default is ' ' (space).
|
||||
*/
|
||||
public static final String MMS_TEXT_CONCAT_SEPARATOR = "bugle_mms_text_concat_separator";
|
||||
public static final String MMS_TEXT_CONCAT_SEPARATOR_DEFAULT = " ";
|
||||
|
||||
/**
|
||||
* Whether to enable transcoding GIFs. We sometimes need to compress GIFs to make them small
|
||||
* enough to send via MMS (which often limits messages to 1 MB in size).
|
||||
*/
|
||||
public static final String ENABLE_GIF_TRANSCODING = "bugle_gif_transcoding";
|
||||
public static final boolean ENABLE_GIF_TRANSCODING_DEFAULT = true;
|
||||
}
|
||||
|
||||
@@ -17,304 +17,22 @@
|
||||
|
||||
package com.android.messaging.util;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.telephony.SmsMessage;
|
||||
import android.text.TextUtils;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.messaging.Factory;
|
||||
import com.android.messaging.R;
|
||||
import com.android.messaging.datamodel.SyncManager;
|
||||
import com.android.messaging.datamodel.action.DumpDatabaseAction;
|
||||
import com.android.messaging.datamodel.action.LogTelephonyDatabaseAction;
|
||||
import com.android.messaging.sms.MmsUtils;
|
||||
import com.android.messaging.ui.UIIntents;
|
||||
import com.android.messaging.ui.debug.DebugSmsMmsFromDumpFileDialogFragment;
|
||||
import com.google.common.io.ByteStreams;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StreamCorruptedException;
|
||||
|
||||
public class DebugUtils {
|
||||
private static final String TAG = "bugle.util.DebugUtils";
|
||||
|
||||
private static boolean sDebugNoise;
|
||||
private static boolean sDebugClassZeroSms;
|
||||
private static MediaPlayer [] sMediaPlayer;
|
||||
private static final Object sLock = new Object();
|
||||
|
||||
public static final int DEBUG_SOUND_SERVER_REQUEST = 0;
|
||||
public static final int DEBUG_SOUND_DB_OP = 1;
|
||||
|
||||
public static void maybePlayDebugNoise(final Context context, final int sound) {
|
||||
if (sDebugNoise) {
|
||||
synchronized (sLock) {
|
||||
try {
|
||||
if (sMediaPlayer == null) {
|
||||
sMediaPlayer = new MediaPlayer[2];
|
||||
sMediaPlayer[DEBUG_SOUND_SERVER_REQUEST] =
|
||||
MediaPlayer.create(context, R.raw.server_request_debug);
|
||||
sMediaPlayer[DEBUG_SOUND_DB_OP] =
|
||||
MediaPlayer.create(context, R.raw.db_op_debug);
|
||||
sMediaPlayer[DEBUG_SOUND_DB_OP].setVolume(1.0F, 1.0F);
|
||||
sMediaPlayer[DEBUG_SOUND_SERVER_REQUEST].setVolume(0.3F, 0.3F);
|
||||
}
|
||||
if (sMediaPlayer[sound] != null) {
|
||||
sMediaPlayer[sound].start();
|
||||
}
|
||||
} catch (final IllegalArgumentException e) {
|
||||
LogUtil.e(TAG, "MediaPlayer exception", e);
|
||||
} catch (final SecurityException e) {
|
||||
LogUtil.e(TAG, "MediaPlayer exception", e);
|
||||
} catch (final IllegalStateException e) {
|
||||
LogUtil.e(TAG, "MediaPlayer exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isDebugEnabled() {
|
||||
return BugleGservices.get().getBoolean(BugleGservicesKeys.ENABLE_DEBUGGING_FEATURES,
|
||||
BugleGservicesKeys.ENABLE_DEBUGGING_FEATURES_DEFAULT);
|
||||
}
|
||||
|
||||
public abstract static class DebugAction {
|
||||
final String mTitle;
|
||||
public DebugAction(final String title) {
|
||||
mTitle = title;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
return mTitle;
|
||||
}
|
||||
|
||||
public abstract void run();
|
||||
}
|
||||
|
||||
public static void showDebugOptions(final Activity host) {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(host);
|
||||
|
||||
final ArrayAdapter<DebugAction> arrayAdapter = new ArrayAdapter<DebugAction>(
|
||||
host, android.R.layout.simple_list_item_1);
|
||||
|
||||
arrayAdapter.add(new DebugAction("Dump Database") {
|
||||
@Override
|
||||
public void run() {
|
||||
DumpDatabaseAction.dumpDatabase();
|
||||
}
|
||||
});
|
||||
|
||||
arrayAdapter.add(new DebugAction("Log Telephony Data") {
|
||||
@Override
|
||||
public void run() {
|
||||
LogTelephonyDatabaseAction.dumpDatabase();
|
||||
}
|
||||
});
|
||||
|
||||
arrayAdapter.add(new DebugAction("Toggle Noise") {
|
||||
@Override
|
||||
public void run() {
|
||||
sDebugNoise = !sDebugNoise;
|
||||
}
|
||||
});
|
||||
|
||||
arrayAdapter.add(new DebugAction("Force sync SMS") {
|
||||
@Override
|
||||
public void run() {
|
||||
final BuglePrefs prefs = BuglePrefs.getApplicationPrefs();
|
||||
prefs.putLong(BuglePrefsKeys.LAST_FULL_SYNC_TIME, -1);
|
||||
SyncManager.forceSync();
|
||||
}
|
||||
});
|
||||
|
||||
arrayAdapter.add(new DebugAction("Sync SMS") {
|
||||
@Override
|
||||
public void run() {
|
||||
SyncManager.sync();
|
||||
}
|
||||
});
|
||||
|
||||
arrayAdapter.add(new DebugAction("Load SMS/MMS from dump file") {
|
||||
@Override
|
||||
public void run() {
|
||||
new DebugSmsMmsDumpTask(host,
|
||||
DebugSmsMmsFromDumpFileDialogFragment.ACTION_LOAD).executeOnThreadPool();
|
||||
}
|
||||
});
|
||||
|
||||
arrayAdapter.add(new DebugAction("Email SMS/MMS dump file") {
|
||||
@Override
|
||||
public void run() {
|
||||
new DebugSmsMmsDumpTask(host,
|
||||
DebugSmsMmsFromDumpFileDialogFragment.ACTION_EMAIL).executeOnThreadPool();
|
||||
}
|
||||
});
|
||||
|
||||
arrayAdapter.add(new DebugAction("MMS Config...") {
|
||||
@Override
|
||||
public void run() {
|
||||
UIIntents.get().launchDebugMmsConfigActivity(host);
|
||||
}
|
||||
});
|
||||
|
||||
arrayAdapter.add(new DebugAction(sDebugClassZeroSms ? "Turn off Class 0 sms test" :
|
||||
"Turn on Class Zero test") {
|
||||
@Override
|
||||
public void run() {
|
||||
sDebugClassZeroSms = !sDebugClassZeroSms;
|
||||
}
|
||||
});
|
||||
|
||||
arrayAdapter.add(new DebugAction("Test sharing a file URI") {
|
||||
@Override
|
||||
public void run() {
|
||||
shareFileUri();
|
||||
}
|
||||
});
|
||||
|
||||
builder.setAdapter(arrayAdapter, (arg0, pos) -> arrayAdapter.getItem(pos).run());
|
||||
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
/**
|
||||
* Task to list all the dump files and perform an action on it
|
||||
*/
|
||||
private static class DebugSmsMmsDumpTask extends SafeAsyncTask<Void, Void, String[]> {
|
||||
private final String mAction;
|
||||
private final Activity mHost;
|
||||
|
||||
public DebugSmsMmsDumpTask(final Activity host, final String action) {
|
||||
mHost = host;
|
||||
mAction = action;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(final String[] result) {
|
||||
if (result == null || result.length < 1) {
|
||||
return;
|
||||
}
|
||||
final FragmentManager fragmentManager = mHost.getFragmentManager();
|
||||
final FragmentTransaction ft = fragmentManager.beginTransaction();
|
||||
final DebugSmsMmsFromDumpFileDialogFragment dialog =
|
||||
DebugSmsMmsFromDumpFileDialogFragment.newInstance(result, mAction);
|
||||
dialog.show(fragmentManager, ""/*tag*/);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] doInBackgroundTimed(final Void... params) {
|
||||
final File dir = DebugUtils.getDebugFilesDir();
|
||||
return dir.list((dir1, filename) -> filename != null
|
||||
&& ((mAction == DebugSmsMmsFromDumpFileDialogFragment.ACTION_EMAIL
|
||||
&& filename.equals(DumpDatabaseAction.DUMP_NAME))
|
||||
|| filename.startsWith(MmsUtils.MMS_DUMP_PREFIX)
|
||||
|| filename.startsWith(MmsUtils.SMS_DUMP_PREFIX)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dump the received raw SMS data into a file on external storage
|
||||
*
|
||||
* @param id The ID to use as part of the dump file name
|
||||
* @param messages The raw SMS data
|
||||
*/
|
||||
public static void dumpSms(final long id, final android.telephony.SmsMessage[] messages,
|
||||
final String format) {
|
||||
try {
|
||||
final String dumpFileName = MmsUtils.SMS_DUMP_PREFIX + id;
|
||||
final File dumpFile = DebugUtils.getDebugFile(dumpFileName, true);
|
||||
if (dumpFile != null) {
|
||||
final FileOutputStream fos = new FileOutputStream(dumpFile);
|
||||
final DataOutputStream dos = new DataOutputStream(fos);
|
||||
try {
|
||||
final int chars = (TextUtils.isEmpty(format) ? 0 : format.length());
|
||||
dos.writeInt(chars);
|
||||
if (chars > 0) {
|
||||
dos.writeUTF(format);
|
||||
}
|
||||
dos.writeInt(messages.length);
|
||||
for (final android.telephony.SmsMessage message : messages) {
|
||||
final byte[] pdu = message.getPdu();
|
||||
dos.writeInt(pdu.length);
|
||||
dos.write(pdu, 0, pdu.length);
|
||||
}
|
||||
dos.flush();
|
||||
} finally {
|
||||
dos.close();
|
||||
ensureReadable(dumpFile);
|
||||
}
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
LogUtil.e(LogUtil.BUGLE_TAG, "dumpSms: " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load MMS/SMS from the dump file
|
||||
*/
|
||||
public static SmsMessage[] retreiveSmsFromDumpFile(final String dumpFileName) {
|
||||
SmsMessage[] messages = null;
|
||||
final File inputFile = DebugUtils.getDebugFile(dumpFileName, false);
|
||||
if (inputFile != null) {
|
||||
FileInputStream fis = null;
|
||||
DataInputStream dis = null;
|
||||
try {
|
||||
fis = new FileInputStream(inputFile);
|
||||
dis = new DataInputStream(fis);
|
||||
|
||||
// SMS dump
|
||||
String format = null;
|
||||
final int chars = dis.readInt();
|
||||
if (chars > 0) {
|
||||
format = dis.readUTF();
|
||||
}
|
||||
final int count = dis.readInt();
|
||||
final SmsMessage[] messagesTemp = new SmsMessage[count];
|
||||
for (int i = 0; i < count; i++) {
|
||||
final int length = dis.readInt();
|
||||
final byte[] pdu = new byte[length];
|
||||
dis.read(pdu, 0, length);
|
||||
messagesTemp[i] = SmsMessage.createFromPdu(pdu, format);
|
||||
}
|
||||
messages = messagesTemp;
|
||||
} catch (final FileNotFoundException e) {
|
||||
// Nothing to do
|
||||
} catch (final StreamCorruptedException e) {
|
||||
// Nothing to do
|
||||
} catch (final IOException e) {
|
||||
// Nothing to do
|
||||
} finally {
|
||||
if (dis != null) {
|
||||
try {
|
||||
dis.close();
|
||||
} catch (final IOException e) {
|
||||
// Nothing to do
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return messages;
|
||||
}
|
||||
|
||||
public static File getDebugFile(final String fileName, final boolean create) {
|
||||
final File dir = getDebugFilesDir();
|
||||
final File file = new File(dir, fileName);
|
||||
@@ -416,24 +134,4 @@ public class DebugUtils {
|
||||
// Never found ourself in the stack?!
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a boolean indicating whether ClassZero debugging is enabled. If enabled, any received
|
||||
* sms is treated as if it were a class zero message and displayed by the ClassZeroActivity.
|
||||
*/
|
||||
public static boolean debugClassZeroSmsEnabled() {
|
||||
return sDebugClassZeroSms;
|
||||
}
|
||||
|
||||
/** Shares a ringtone file via file URI. */
|
||||
private static void shareFileUri() {
|
||||
final String packageName = "com.android.messaging";
|
||||
final String fileName = "/system/media/audio/ringtones/Andromeda.ogg";
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_SEND);
|
||||
intent.setPackage(packageName);
|
||||
intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + fileName));
|
||||
intent.setType("image/*");
|
||||
Factory.get().getApplicationContext().startActivity(intent);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,9 +42,6 @@ public class GifTranscoder {
|
||||
}
|
||||
|
||||
public static boolean transcode(Context context, String filePath, String outFilePath) {
|
||||
if (!isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
final long inputSize = new File(filePath).length();
|
||||
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||
final boolean success = transcodeInternal(filePath, outFilePath);
|
||||
@@ -77,19 +74,6 @@ public class GifTranscoder {
|
||||
}
|
||||
|
||||
public static boolean canBeTranscoded(int width, int height) {
|
||||
if (!isEnabled()) {
|
||||
return false;
|
||||
}
|
||||
return width >= MIN_WIDTH && height >= MIN_HEIGHT;
|
||||
}
|
||||
|
||||
private static boolean isEnabled() {
|
||||
final boolean enabled = BugleGservices.get().getBoolean(
|
||||
BugleGservicesKeys.ENABLE_GIF_TRANSCODING,
|
||||
BugleGservicesKeys.ENABLE_GIF_TRANSCODING_DEFAULT);
|
||||
if (!enabled) {
|
||||
LogUtil.w(TAG, "GIF transcoding is disabled");
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,293 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 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 com.android.messaging.util;
|
||||
|
||||
import android.os.Process;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.messaging.Factory;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.logging.FileHandler;
|
||||
import java.util.logging.Formatter;
|
||||
import java.util.logging.Handler;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Save the app's own log to dump along with adb bugreport
|
||||
*/
|
||||
public abstract class LogSaver {
|
||||
/**
|
||||
* Writes the accumulated log entries, from oldest to newest, to the specified PrintWriter.
|
||||
* Log lines are emitted in much the same form as logcat -v threadtime -- specifically,
|
||||
* lines will include a timestamp, pid, tid, level, and tag.
|
||||
*
|
||||
* @param writer The PrintWriter to output
|
||||
*/
|
||||
public abstract void dump(PrintWriter writer);
|
||||
|
||||
/**
|
||||
* Log a line
|
||||
*
|
||||
* @param level The log level to use
|
||||
* @param tag The log tag
|
||||
* @param msg The message of the log line
|
||||
*/
|
||||
public abstract void log(int level, String tag, String msg);
|
||||
|
||||
/**
|
||||
* Check if the LogSaver still matches the current Gservices settings
|
||||
*
|
||||
* @return true if matches, false otherwise
|
||||
*/
|
||||
public abstract boolean isCurrent();
|
||||
|
||||
private LogSaver() {
|
||||
}
|
||||
|
||||
public static LogSaver newInstance() {
|
||||
final boolean persistent = BugleGservices.get().getBoolean(
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER,
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_DEFAULT);
|
||||
if (persistent) {
|
||||
final int setSize = BugleGservices.get().getInt(
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_ROTATION_SET_SIZE,
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_ROTATION_SET_SIZE_DEFAULT);
|
||||
final int fileLimitBytes = BugleGservices.get().getInt(
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_FILE_LIMIT_BYTES,
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_FILE_LIMIT_BYTES_DEFAULT);
|
||||
return new DiskLogSaver(setSize, fileLimitBytes);
|
||||
} else {
|
||||
final int size = BugleGservices.get().getInt(
|
||||
BugleGservicesKeys.IN_MEMORY_LOGSAVER_RECORD_COUNT,
|
||||
BugleGservicesKeys.IN_MEMORY_LOGSAVER_RECORD_COUNT_DEFAULT);
|
||||
return new MemoryLogSaver(size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A circular in-memory log to be used to log potentially verbose logs. The logs will be
|
||||
* persisted in memory in the application and can be dumped by various dump() methods.
|
||||
* For example, adb shell dumpsys activity provider com.android.messaging.
|
||||
* The dump will also show up in bugreports.
|
||||
*/
|
||||
private static final class MemoryLogSaver extends LogSaver {
|
||||
/**
|
||||
* Record to store a single log entry. Stores timestamp, tid, level, tag, and message.
|
||||
* It can be reused when the circular log rolls over. This avoids creating new objects.
|
||||
*/
|
||||
private static class LogRecord {
|
||||
int mTid;
|
||||
String mLevelString;
|
||||
long mTimeMillis; // from System.currentTimeMillis
|
||||
String mTag;
|
||||
String mMessage;
|
||||
|
||||
LogRecord() {
|
||||
}
|
||||
|
||||
void set(int tid, int level, long time, String tag, String message) {
|
||||
this.mTid = tid;
|
||||
this.mTimeMillis = time;
|
||||
this.mTag = tag;
|
||||
this.mMessage = message;
|
||||
this.mLevelString = getLevelString(level);
|
||||
}
|
||||
}
|
||||
|
||||
private final int mSize;
|
||||
private final CircularArray<LogRecord> mLogList;
|
||||
private final Object mLock;
|
||||
|
||||
private final SimpleDateFormat mSdf = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
|
||||
|
||||
public MemoryLogSaver(final int size) {
|
||||
mSize = size;
|
||||
mLogList = new CircularArray<LogRecord>(size);
|
||||
mLock = new Object();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter writer) {
|
||||
int pid = Process.myPid();
|
||||
synchronized (mLock) {
|
||||
for (int i = 0; i < mLogList.count(); i++) {
|
||||
LogRecord rec = mLogList.get(i);
|
||||
writer.println(String.format("%s %5d %5d %s %s: %s",
|
||||
mSdf.format(rec.mTimeMillis),
|
||||
pid, rec.mTid, rec.mLevelString, rec.mTag, rec.mMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(int level, String tag, String msg) {
|
||||
synchronized (mLock) {
|
||||
LogRecord rec = mLogList.getFree();
|
||||
if (rec == null) {
|
||||
rec = new LogRecord();
|
||||
}
|
||||
rec.set(Process.myTid(), level, System.currentTimeMillis(), tag, msg);
|
||||
mLogList.add(rec);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrent() {
|
||||
final boolean persistent = BugleGservices.get().getBoolean(
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER,
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_DEFAULT);
|
||||
if (persistent) {
|
||||
return false;
|
||||
}
|
||||
final int size = BugleGservices.get().getInt(
|
||||
BugleGservicesKeys.IN_MEMORY_LOGSAVER_RECORD_COUNT,
|
||||
BugleGservicesKeys.IN_MEMORY_LOGSAVER_RECORD_COUNT_DEFAULT);
|
||||
return size == mSize;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A persistent, on-disk log saver. It uses the standard Java util logger along with
|
||||
* a rotation log file set to store the logs in app's local file directory "app_logs".
|
||||
*/
|
||||
private static final class DiskLogSaver extends LogSaver {
|
||||
private static final String DISK_LOG_DIR_NAME = "logs";
|
||||
|
||||
private final int mSetSize;
|
||||
private final int mFileLimitBytes;
|
||||
private Logger mDiskLogger;
|
||||
|
||||
public DiskLogSaver(final int setSize, final int fileLimitBytes) {
|
||||
Assert.isTrue(setSize > 0);
|
||||
Assert.isTrue(fileLimitBytes > 0);
|
||||
mSetSize = setSize;
|
||||
mFileLimitBytes = fileLimitBytes;
|
||||
initDiskLog();
|
||||
}
|
||||
|
||||
private static void clearDefaultHandlers(Logger logger) {
|
||||
Assert.notNull(logger);
|
||||
for (Handler handler : logger.getHandlers()) {
|
||||
logger.removeHandler(handler);
|
||||
}
|
||||
}
|
||||
|
||||
private void initDiskLog() {
|
||||
mDiskLogger = Logger.getLogger(LogUtil.BUGLE_TAG);
|
||||
// We don't want the default console handler
|
||||
clearDefaultHandlers(mDiskLogger);
|
||||
// Don't want duplicate print in system log
|
||||
mDiskLogger.setUseParentHandlers(false);
|
||||
// FileHandler manages the log files in a fixed rotation set
|
||||
final File logDir = Factory.get().getApplicationContext().getDir(
|
||||
DISK_LOG_DIR_NAME, 0/*mode*/);
|
||||
FileHandler handler = null;
|
||||
try {
|
||||
handler = new FileHandler(
|
||||
logDir + "/%g.log", mFileLimitBytes, mSetSize, true/*append*/);
|
||||
} catch (Exception e) {
|
||||
Log.e(LogUtil.BUGLE_TAG, "LogSaver: fail to init disk logger", e);
|
||||
return;
|
||||
}
|
||||
final Formatter formatter = new Formatter() {
|
||||
@Override
|
||||
public String format(java.util.logging.LogRecord r) {
|
||||
return r.getMessage();
|
||||
}
|
||||
};
|
||||
handler.setFormatter(formatter);
|
||||
handler.setLevel(Level.ALL);
|
||||
mDiskLogger.addHandler(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dump(PrintWriter writer) {
|
||||
for (int i = mSetSize - 1; i >= 0; i--) {
|
||||
final File logDir = Factory.get().getApplicationContext().getDir(
|
||||
DISK_LOG_DIR_NAME, 0/*mode*/);
|
||||
final String logFilePath = logDir + "/" + i + ".log";
|
||||
try {
|
||||
final File logFile = new File(logFilePath);
|
||||
if (!logFile.exists()) {
|
||||
continue;
|
||||
}
|
||||
final BufferedReader reader = new BufferedReader(new FileReader(logFile));
|
||||
for (String line; (line = reader.readLine()) != null;) {
|
||||
line = line.trim();
|
||||
writer.println(line);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.w(LogUtil.BUGLE_TAG, "LogSaver: can not find log file " + logFilePath);
|
||||
} catch (IOException e) {
|
||||
Log.w(LogUtil.BUGLE_TAG, "LogSaver: can not read log file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(int level, String tag, String msg) {
|
||||
final SimpleDateFormat sdf = new SimpleDateFormat("MM-dd HH:mm:ss.SSS");
|
||||
mDiskLogger.info(String.format("%s %5d %5d %s %s: %s\n",
|
||||
sdf.format(System.currentTimeMillis()),
|
||||
Process.myPid(), Process.myTid(), getLevelString(level), tag, msg));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCurrent() {
|
||||
final boolean persistent = BugleGservices.get().getBoolean(
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER,
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_DEFAULT);
|
||||
if (!persistent) {
|
||||
return false;
|
||||
}
|
||||
final int setSize = BugleGservices.get().getInt(
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_ROTATION_SET_SIZE,
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_ROTATION_SET_SIZE_DEFAULT);
|
||||
final int fileLimitBytes = BugleGservices.get().getInt(
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_FILE_LIMIT_BYTES,
|
||||
BugleGservicesKeys.PERSISTENT_LOGSAVER_FILE_LIMIT_BYTES_DEFAULT);
|
||||
return setSize == mSetSize && fileLimitBytes == mFileLimitBytes;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getLevelString(final int level) {
|
||||
switch (level) {
|
||||
case android.util.Log.DEBUG:
|
||||
return "D";
|
||||
case android.util.Log.WARN:
|
||||
return "W";
|
||||
case android.util.Log.INFO:
|
||||
return "I";
|
||||
case android.util.Log.VERBOSE:
|
||||
return "V";
|
||||
case android.util.Log.ERROR:
|
||||
return "E";
|
||||
case android.util.Log.ASSERT:
|
||||
return "A";
|
||||
default:
|
||||
return "?";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,33 +36,6 @@ public class LogUtil {
|
||||
public static final int INFO = android.util.Log.INFO;
|
||||
public static final int ERROR = android.util.Log.ERROR;
|
||||
|
||||
// If this is non-null, DEBUG and higher logs will be tracked in-memory. It will not include
|
||||
// VERBOSE logs.
|
||||
private static LogSaver sDebugLogSaver;
|
||||
private static volatile boolean sCaptureDebugLogs;
|
||||
|
||||
/**
|
||||
* Read Gservices to see if logging should be enabled.
|
||||
*/
|
||||
public static void refreshGservices(final BugleGservices gservices) {
|
||||
sCaptureDebugLogs = gservices.getBoolean(
|
||||
BugleGservicesKeys.ENABLE_LOG_SAVER,
|
||||
BugleGservicesKeys.ENABLE_LOG_SAVER_DEFAULT);
|
||||
if (sCaptureDebugLogs && (sDebugLogSaver == null || !sDebugLogSaver.isCurrent())) {
|
||||
// We were not capturing logs before. We are now.
|
||||
sDebugLogSaver = LogSaver.newInstance();
|
||||
} else if (!sCaptureDebugLogs && sDebugLogSaver != null) {
|
||||
// We were capturing logs. We aren't anymore.
|
||||
sDebugLogSaver = null;
|
||||
}
|
||||
}
|
||||
|
||||
// This is called from FactoryImpl once the Gservices class is initialized.
|
||||
public static void initializeGservices (final BugleGservices gservices) {
|
||||
gservices.registerForChanges(() -> refreshGservices(gservices));
|
||||
refreshGservices(gservices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a {@link #VERBOSE} log message.
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
@@ -214,26 +187,6 @@ public class LogUtil {
|
||||
*/
|
||||
private static void println(final int level, final String tag, final String msg) {
|
||||
android.util.Log.println(level, tag, msg);
|
||||
|
||||
LogSaver serviceLog = sDebugLogSaver;
|
||||
if (serviceLog != null && level >= android.util.Log.DEBUG) {
|
||||
serviceLog.log(level, tag, msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save logging into LogSaver only, for dumping to bug report
|
||||
*
|
||||
* @param level The priority/type of this log message
|
||||
* @param tag Used to identify the source of a log message. It usually identifies
|
||||
* the class or activity where the log call occurs.
|
||||
* @param msg The message you would like logged.
|
||||
*/
|
||||
public static void save(final int level, final String tag, final String msg) {
|
||||
LogSaver serviceLog = sDebugLogSaver;
|
||||
if (serviceLog != null) {
|
||||
serviceLog.log(level, tag, msg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,11 +213,4 @@ public class LogUtil {
|
||||
return "Redacted-" + text.length();
|
||||
}
|
||||
}
|
||||
|
||||
public static void dump(java.io.PrintWriter out) {
|
||||
final LogSaver logsaver = sDebugLogSaver;
|
||||
if (logsaver != null) {
|
||||
logsaver.dump(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
* Copyright (C) 2024 The LineageOS Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -59,8 +60,6 @@ public class LoggingTimer {
|
||||
|
||||
final String logMessage = String.format("Used %dms for %s", elapsedMs, mName);
|
||||
|
||||
LogUtil.save(LogUtil.DEBUG, mTag, logMessage);
|
||||
|
||||
if (mWarnLimitMillis != NO_WARN_LIMIT && elapsedMs > mWarnLimitMillis) {
|
||||
LogUtil.w(mTag, logMessage);
|
||||
} else if (LogUtil.isLoggable(mTag, LogUtil.VERBOSE)) {
|
||||
|
||||
Reference in New Issue
Block a user