Home | History | Annotate | Download | only in provider
      1 /*
      2  * Copyright (C) 2006 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 android.provider;
     18 
     19 import com.android.internal.telephony.CallerInfo;
     20 import com.android.internal.telephony.Connection;
     21 
     22 import android.content.ContentResolver;
     23 import android.content.ContentValues;
     24 import android.content.Context;
     25 import android.database.Cursor;
     26 import android.net.Uri;
     27 import android.text.TextUtils;
     28 
     29 /**
     30  * The CallLog provider contains information about placed and received calls.
     31  */
     32 public class CallLog {
     33     public static final String AUTHORITY = "call_log";
     34 
     35     /**
     36      * The content:// style URL for this provider
     37      */
     38     public static final Uri CONTENT_URI =
     39         Uri.parse("content://" + AUTHORITY);
     40 
     41     /**
     42      * Contains the recent calls.
     43      */
     44     public static class Calls implements BaseColumns {
     45         /**
     46          * The content:// style URL for this table
     47          */
     48         public static final Uri CONTENT_URI =
     49                 Uri.parse("content://call_log/calls");
     50 
     51         /**
     52          * The content:// style URL for filtering this table on phone numbers
     53          */
     54         public static final Uri CONTENT_FILTER_URI =
     55                 Uri.parse("content://call_log/calls/filter");
     56 
     57         /**
     58          * The default sort order for this table
     59          */
     60         public static final String DEFAULT_SORT_ORDER = "date DESC";
     61 
     62         /**
     63          * The MIME type of {@link #CONTENT_URI} and {@link #CONTENT_FILTER_URI}
     64          * providing a directory of calls.
     65          */
     66         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/calls";
     67 
     68         /**
     69          * The MIME type of a {@link #CONTENT_URI} sub-directory of a single
     70          * call.
     71          */
     72         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/calls";
     73 
     74         /**
     75          * The type of the call (incoming, outgoing or missed).
     76          * <P>Type: INTEGER (int)</P>
     77          */
     78         public static final String TYPE = "type";
     79 
     80         public static final int INCOMING_TYPE = 1;
     81         public static final int OUTGOING_TYPE = 2;
     82         public static final int MISSED_TYPE = 3;
     83 
     84         /**
     85          * The phone number as the user entered it.
     86          * <P>Type: TEXT</P>
     87          */
     88         public static final String NUMBER = "number";
     89 
     90         /**
     91          * The date the call occured, in milliseconds since the epoch
     92          * <P>Type: INTEGER (long)</P>
     93          */
     94         public static final String DATE = "date";
     95 
     96         /**
     97          * The duration of the call in seconds
     98          * <P>Type: INTEGER (long)</P>
     99          */
    100         public static final String DURATION = "duration";
    101 
    102         /**
    103          * Whether or not the call has been acknowledged
    104          * <P>Type: INTEGER (boolean)</P>
    105          */
    106         public static final String NEW = "new";
    107 
    108         /**
    109          * The cached name associated with the phone number, if it exists.
    110          * This value is not guaranteed to be current, if the contact information
    111          * associated with this number has changed.
    112          * <P>Type: TEXT</P>
    113          */
    114         public static final String CACHED_NAME = "name";
    115 
    116         /**
    117          * The cached number type (Home, Work, etc) associated with the
    118          * phone number, if it exists.
    119          * This value is not guaranteed to be current, if the contact information
    120          * associated with this number has changed.
    121          * <P>Type: INTEGER</P>
    122          */
    123         public static final String CACHED_NUMBER_TYPE = "numbertype";
    124 
    125         /**
    126          * The cached number label, for a custom number type, associated with the
    127          * phone number, if it exists.
    128          * This value is not guaranteed to be current, if the contact information
    129          * associated with this number has changed.
    130          * <P>Type: TEXT</P>
    131          */
    132         public static final String CACHED_NUMBER_LABEL = "numberlabel";
    133 
    134         /**
    135          * Adds a call to the call log.
    136          *
    137          * @param ci the CallerInfo object to get the target contact from.  Can be null
    138          * if the contact is unknown.
    139          * @param context the context used to get the ContentResolver
    140          * @param number the phone number to be added to the calls db
    141          * @param presentation the number presenting rules set by the network for
    142          *        "allowed", "payphone", "restricted" or "unknown"
    143          * @param callType enumerated values for "incoming", "outgoing", or "missed"
    144          * @param start time stamp for the call in milliseconds
    145          * @param duration call duration in seconds
    146          *
    147          * {@hide}
    148          */
    149         public static Uri addCall(CallerInfo ci, Context context, String number,
    150                 int presentation, int callType, long start, int duration) {
    151             final ContentResolver resolver = context.getContentResolver();
    152 
    153             // If this is a private number then set the number to Private, otherwise check
    154             // if the number field is empty and set the number to Unavailable
    155             if (presentation == Connection.PRESENTATION_RESTRICTED) {
    156                 number = CallerInfo.PRIVATE_NUMBER;
    157                 if (ci != null) ci.name = "";
    158             } else if (presentation == Connection.PRESENTATION_PAYPHONE) {
    159                 number = CallerInfo.PAYPHONE_NUMBER;
    160                 if (ci != null) ci.name = "";
    161             } else if (TextUtils.isEmpty(number)
    162                     || presentation == Connection.PRESENTATION_UNKNOWN) {
    163                 number = CallerInfo.UNKNOWN_NUMBER;
    164                 if (ci != null) ci.name = "";
    165             }
    166 
    167             ContentValues values = new ContentValues(5);
    168 
    169             values.put(NUMBER, number);
    170             values.put(TYPE, Integer.valueOf(callType));
    171             values.put(DATE, Long.valueOf(start));
    172             values.put(DURATION, Long.valueOf(duration));
    173             values.put(NEW, Integer.valueOf(1));
    174             if (ci != null) {
    175                 values.put(CACHED_NAME, ci.name);
    176                 values.put(CACHED_NUMBER_TYPE, ci.numberType);
    177                 values.put(CACHED_NUMBER_LABEL, ci.numberLabel);
    178             }
    179 
    180             if ((ci != null) && (ci.person_id > 0)) {
    181                 ContactsContract.Contacts.markAsContacted(resolver, ci.person_id);
    182             }
    183 
    184             Uri result = resolver.insert(CONTENT_URI, values);
    185 
    186             removeExpiredEntries(context);
    187 
    188             return result;
    189         }
    190 
    191         /**
    192          * Query the call log database for the last dialed number.
    193          * @param context Used to get the content resolver.
    194          * @return The last phone number dialed (outgoing) or an empty
    195          * string if none exist yet.
    196          */
    197         public static String getLastOutgoingCall(Context context) {
    198             final ContentResolver resolver = context.getContentResolver();
    199             Cursor c = null;
    200             try {
    201                 c = resolver.query(
    202                     CONTENT_URI,
    203                     new String[] {NUMBER},
    204                     TYPE + " = " + OUTGOING_TYPE,
    205                     null,
    206                     DEFAULT_SORT_ORDER + " LIMIT 1");
    207                 if (c == null || !c.moveToFirst()) {
    208                     return "";
    209                 }
    210                 return c.getString(0);
    211             } finally {
    212                 if (c != null) c.close();
    213             }
    214         }
    215 
    216         private static void removeExpiredEntries(Context context) {
    217             final ContentResolver resolver = context.getContentResolver();
    218             resolver.delete(CONTENT_URI, "_id IN " +
    219                     "(SELECT _id FROM calls ORDER BY " + DEFAULT_SORT_ORDER
    220                     + " LIMIT -1 OFFSET 500)", null);
    221         }
    222     }
    223 }
    224