1 /* 2 * Copyright (C) 2015 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.messaging.datamodel.action; 18 19 import android.content.Context; 20 import android.database.Cursor; 21 import android.net.Uri; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.provider.Telephony.Threads; 25 import android.provider.Telephony.ThreadsColumns; 26 27 import com.android.messaging.Factory; 28 import com.android.messaging.mmslib.SqliteWrapper; 29 import com.android.messaging.util.DebugUtils; 30 import com.android.messaging.util.LogUtil; 31 32 public class LogTelephonyDatabaseAction extends Action implements Parcelable { 33 // Because we use sanitizePII, we should also use BUGLE_TAG 34 private static final String TAG = LogUtil.BUGLE_TAG; 35 36 private static final String[] ALL_THREADS_PROJECTION = { 37 Threads._ID, 38 Threads.DATE, 39 Threads.MESSAGE_COUNT, 40 Threads.RECIPIENT_IDS, 41 Threads.SNIPPET, 42 Threads.SNIPPET_CHARSET, 43 Threads.READ, 44 Threads.ERROR, 45 Threads.HAS_ATTACHMENT }; 46 47 // Constants from the Telephony Database 48 private static final int ID = 0; 49 private static final int DATE = 1; 50 private static final int MESSAGE_COUNT = 2; 51 private static final int RECIPIENT_IDS = 3; 52 private static final int SNIPPET = 4; 53 private static final int SNIPPET_CHAR_SET = 5; 54 private static final int READ = 6; 55 private static final int ERROR = 7; 56 private static final int HAS_ATTACHMENT = 8; 57 58 /** 59 * Log telephony data to logcat 60 */ dumpDatabase()61 public static void dumpDatabase() { 62 final LogTelephonyDatabaseAction action = new LogTelephonyDatabaseAction(); 63 action.start(); 64 } 65 LogTelephonyDatabaseAction()66 private LogTelephonyDatabaseAction() { 67 } 68 69 @Override executeAction()70 protected Object executeAction() { 71 final Context context = Factory.get().getApplicationContext(); 72 73 if (!DebugUtils.isDebugEnabled()) { 74 LogUtil.e(TAG, "Can't log telephony database unless debugging is enabled"); 75 return null; 76 } 77 78 if (!LogUtil.isLoggable(TAG, LogUtil.DEBUG)) { 79 LogUtil.w(TAG, "Can't log telephony database unless DEBUG is turned on for TAG: " + 80 TAG); 81 return null; 82 } 83 84 LogUtil.d(TAG, "\n"); 85 LogUtil.d(TAG, "Dump of canoncial_addresses table"); 86 LogUtil.d(TAG, "*********************************"); 87 88 Cursor cursor = SqliteWrapper.query(context, context.getContentResolver(), 89 Uri.parse("content://mms-sms/canonical-addresses"), null, null, null, null); 90 91 if (cursor == null) { 92 LogUtil.w(TAG, "null Cursor in content://mms-sms/canonical-addresses"); 93 } else { 94 try { 95 while (cursor.moveToNext()) { 96 long id = cursor.getLong(0); 97 String number = cursor.getString(1); 98 LogUtil.d(TAG, LogUtil.sanitizePII("id: " + id + " number: " + number)); 99 } 100 } finally { 101 cursor.close(); 102 } 103 } 104 105 LogUtil.d(TAG, "\n"); 106 LogUtil.d(TAG, "Dump of threads table"); 107 LogUtil.d(TAG, "*********************"); 108 109 cursor = SqliteWrapper.query(context, context.getContentResolver(), 110 Threads.CONTENT_URI.buildUpon().appendQueryParameter("simple", "true").build(), 111 ALL_THREADS_PROJECTION, null, null, "date ASC"); 112 try { 113 while (cursor.moveToNext()) { 114 LogUtil.d(TAG, LogUtil.sanitizePII("threadId: " + cursor.getLong(ID) + 115 " " + ThreadsColumns.DATE + " : " + cursor.getLong(DATE) + 116 " " + ThreadsColumns.MESSAGE_COUNT + " : " + cursor.getInt(MESSAGE_COUNT) + 117 " " + ThreadsColumns.SNIPPET + " : " + cursor.getString(SNIPPET) + 118 " " + ThreadsColumns.READ + " : " + cursor.getInt(READ) + 119 " " + ThreadsColumns.ERROR + " : " + cursor.getInt(ERROR) + 120 " " + ThreadsColumns.HAS_ATTACHMENT + " : " + 121 cursor.getInt(HAS_ATTACHMENT) + 122 " " + ThreadsColumns.RECIPIENT_IDS + " : " + 123 cursor.getString(RECIPIENT_IDS))); 124 } 125 } finally { 126 cursor.close(); 127 } 128 129 return null; 130 } 131 LogTelephonyDatabaseAction(final Parcel in)132 private LogTelephonyDatabaseAction(final Parcel in) { 133 super(in); 134 } 135 136 public static final Parcelable.Creator<LogTelephonyDatabaseAction> CREATOR 137 = new Parcelable.Creator<LogTelephonyDatabaseAction>() { 138 @Override 139 public LogTelephonyDatabaseAction createFromParcel(final Parcel in) { 140 return new LogTelephonyDatabaseAction(in); 141 } 142 143 @Override 144 public LogTelephonyDatabaseAction[] newArray(final int size) { 145 return new LogTelephonyDatabaseAction[size]; 146 } 147 }; 148 149 @Override writeToParcel(final Parcel parcel, final int flags)150 public void writeToParcel(final Parcel parcel, final int flags) { 151 writeActionToParcel(parcel, flags); 152 } 153 } 154