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