API Reference | developer.brewmp.com API Reference | developer.brewmp.com

Developer

PIM_AEECLSID_CALLHISTORY

>
Brew Release
Brew MP 1.0.2
See Also
pim_IRecordStore pim_ICallHistoryUtil pim_IRecordStore_AddRef() pim_IRecordStore_Release() pim_IRecordStore_QueryInterface() pim_IRecordStore_GetRecord() pim_IRecordStore_Search() pim_IRecordStore_OnChange() pim_IRecordStore_GetChangesSince()
Description
Implementation of the pim_IRecordStore interface. This class provides a way to interact with the Call History record store to add, delete, update or search records as well as receive notifications and detect changes to the call logs. pim_AEECLSID_CallHistory is the class ID and is also the minimum privilege required to create an instance of the class. If the client holds this privilege, it allows them to create the object as well as act as an observer on callhistory changes (i.e., it grants read access to the CallHistory record store). Holding pim_AEECLSID_CallHistory privilege allows clients to use the following pim_IRecordStore APIs: pim_IRecordStore_AddRef() pim_IRecordStore_Release() pim_IRecordStore_QueryInterface() pim_IRecordStore_GetRecord() pim_IRecordStore_Search() pim_IRecordStore_OnChange() pim_IRecordStore_GetChangesSince() A special privilege pim_AEEPRIVID_CallHistory_Write is required to obtain write access to the callhistory record store. The pim_IRecordStore interface does not specify the record format or the search criteria to be used to find records in the record store. It is left to the class implementing this interface to define them. pim_AEECLSID_CallHistory implements pim_IRecordStore interface and defines the record format, the fields that make a CallHistory record and the search criteria that can be used to perform search operations on the Call History repository. Call History records are made up of one or more Call History fields. Call History fields can be broken up into two types: pre-defined and user-defined. Pre-defined fields are defined by this class with specific types and value formats so that all applications can understand the contents. User-defined fields allow an application to store information associated with a call that is not covered by the pre-defined fields. The user-defined fields must have a "FieldName", pim_ICallHistoryUtil_FieldValueType and the value based on the whether value type is pim_ICallHistoryUtil_ValueNum or pim_ICallHistoryUtil_ValueStr. Not all pre-defined fields may be supported on all devices. The mandatory fields will be supported, but other fields may or may not be supported. Applications can determine supported fields using methods in pim_ICallHistoryUtil interface. The pre-defined fields for this class and the data type and supported values for each field are defined using the pim_CallHistory_Field_XXX format. The record is a collection of such fields and is represented using a UTF-8 encoded character string where each field is a name-value pair seperated by an equal sign ("=") and fields are separated using a delimiter character (semi-colon ";"). For example, a record may look like this: "CallType=1;NumberType=2;NumberPlan=1;Timestamp=922060800;CallDuration=120;Number="8885551234";CallActive=0;" This class should be used in conjunction with pim_ICallHistoryUtil interface to easily and correctly convert from a structured call history record to a pim_IRecordStore record and vice-versa. This class only supports retrieving complete records, i.e., the Offset for pim_IRecordStore_GetRecord() should always be 0. The SearchCriteria supported by this class is defined in the following format (an empty search criterion "" will return all records) and represented using a UTF-8 encoded string: Search :: [SearchClause [AND SearchClause]] SearchClause :: fieldname :: binary-op :: = pattern :: literal-value (Depends on type of field. Could be a number or a string). String literal values must be enclosed within double quotes (e.g. "String Value") The pattern can contain a wildchar character (%), such as "888%". A wildcard can be used anywhere in the pattern string, but performance should be kept in mind while using wildcards. Generally, patterns with the wildcard at the end of the pattern will perform better. While the wildcard can be used for fields with value type pim_ICallHistoryUtil_ValueNum, it is best to use the wildcard with fields that have value type pim_ICallHistoryUtil_ValueStr. Examples of search criteria: "CallType=3" - Matches all records with pim_CallHistory_Field_CallType as pim_CallHistory_CallType_Missed. "Number="8885551234"" - Matches all records with pim_CallHistory_Field_Number equal to "8885551234". "CallType=2 AND Number="858%"" - Matches all incoming calls from phone number starting with 858. Some sample usage scenarios are described below (proper error handling and memory management should be handled by users of the code snippets): Creating a pim_IRecordStore object using pim_AEECLSID_CallHistory pim_IRecordStore* piCallHistoryRecordStore = NULL; int nErr; // Assumption: piEnv is a valid IEnv pointer nErr = IEnv_CreateInstance(piEnv, pim_AEECLSID_CallHistory, (void **)&piCallHistoryRecordStore); if (AEE_SUCCESS != nErr) { // Handle error here. } Adding a record to the call history store A record can be added to the call history record store using pim_IRecordStore interface. Using the pim_ICallHistoryUtil interface to convert from a structured call history record to the format expected by pim_IRecordStore interface will guarantee that records are created and added successfully. For an example of using pim_ICallHistoryUtil to add a call history record, please refer to the usage example in pim_ICallHistoryUtil interface documentation. Deleting a record from the call history store // Assumption: piCallHistoryRecordStore is a valid pim_IRecordStore object // and ID is the pim_IRecordStore_RecordID value obtained from a // previous call to pim_IRecordStore_AddRecord(), pim_IRecordStore_Search() // or pim_IRecordStore_GetChangesSince() int nErr; nErr = pim_IRecordStore_RemoveRecord(piCallHistoryRecordStore, ID); if (AEE_SUCCESS != nErr) { // Handle error here. } Reading a record from the call history store based on a record ID A record can be read from the call history record store using pim_IRecordStore interface. Using the pim_ICallHistoryUtil interface will simplify conversion from the pim_IRecordStore format to a structured call history record. // Assumption: piCallHistoryRecordStore is a valid pim_IRecordStore object // and ID is the pim_IRecordStore_RecordID value obtained from a // previous call to pim_IRecordStore_AddRecord(), pim_IRecordStore_Search() // or pim_IRecordStore_GetChangesSince() unsigned char* Entry = NULL; int EntryLen = 0; int EntryLenReq = 0; // Create a baseline for future comparisons. nErr = pim_IRecordStore_GetRecord(piCallHistoryRecordStore, RecordID, 0, Entry, EntryLen, &EntryLenReq); if (AEE_SUCCESS != nErr) { // Handle error here. } // Remember to deallocate using IENV_FREEIF() after done using Entry. nErr = IEnv_ErrMallocNoZI(piEnv, EntryLenReq, (void **)Entry); if (AEE_SUCCESS != nErr) { // Handle error here. } EntryLen = EntryLenReq; nErr = pim_IRecordStore_GetRecord(piCallHistoryRecordStore, RecordID, 0, Entry, EntryLen, &EntryLenReq); if (AEE_SUCCESS != nErr) { // Handle error here. } // Convert from "Entry" format to pim_ICallHistoryUtil_Field format. For an example of using pim_ICallHistoryUtil to extract call history fields from a pim_IRecordStore record, please refer to the usage example in pim_ICallHistoryUtil interface documentation. Finding records based on certain search criteria Call History records can be obtained based on supported search criteria. One example is searching for all missed calls from the call history records. // Assumption: piCallHistoryRecordStore is a valid pim_IRecordStore object int nErr; pim_IRecordStore_RecordID* IDs = NULL; int IDsLen = 0; int IDsLenReq = 0; unsigned char* pszSearchCriteria = "CallType=3"; // Matches all records with // pim_CallHistory_Field_CallType // as pim_CallHistory_CallType_Missed. nErr = pim_IRecordStore_Search(piCallHistoryRecordStore, pszSearchCriteria, std_strlen((char*)pszSearchCriteria) + 1, IDs, IDsLen, &IDsLenReq); if (AEE_SUCCESS != nErr) { // Handle error here. } // Remember to deallocate using IENV_FREEIF() after done using IDs. nErr = IEnv_ErrMallocNoZI(piEnv, IDsLenReq, (void **)IDs); if (AEE_SUCCESS != nErr) { // Handle error here. } IDsLen = IDsLenReq; nErr = pim_IRecordStore_Search(piCallHistoryRecordStore, pszSearchCriteria, std_strlen(pszSearchCriteria) + 1, IDs, IDsLen, &IDsLenReq); if (AEE_SUCCESS != nErr) { // Handle error here. } // Read record using pim_IRecordStore_GetRecord() as show in // "Reading a record from the call history store based on a record ID" // section. Registering for notification on changes in Call History records Registering for notifications on changes in call history records can be done by simply using the pim_IRecordStore_OnChange() API, but for efficiently determining the type of changes (add, delete, update etc), it is recommended that the client maintain a list of records it has already seen to be compared with the list returned by pim_IRecordStore_GetChangesSince() API. This will also help the client in finding the changes if it is not memory resident. A sequence diagram below also depicts how to use the sequence number to easily find out changes that happened to the Call History records. // Assumption: piCallHistoryRecordStore is a valid pim_IRecordStore object, // piSignal is a valid ISignal object and piEnv is a valid Env object. int64 SeqNum = 0LL; int64 CurrentSeqNum = 0LL; pim_IRecordStore_RecordID* AddedIDs = NULL; int AddedIDsLen = 0; int AddedIDsLenReq = 0; pim_IRecordStore_RecordID* UpdatedIDs = NULL; int UpdatedIDsLen = 0; int UpdatedsLenReq = 0; pim_IRecordStore_RecordID* DeletedIDs = NULL; int DeletedIDsLen = 0; int DeletedLenReq = 0; IQI* piQI = NULL; // If application stored the SeqNum in persistent storage from it's last // execution (this is recommended; as is storing the record IDs of the last // snapshot that the application knew about), read it and use that as SeqNum. // Then update the baseline for future comparisons. nErr = pim_IRecordStore_GetChangesSince(piCallHistoryRecordStore, &CurrentSeqNum, SeqNum, AddedIDs, AddedIDsLen, &AddedIDsLenReq, UpdatedIDs, UpdatedIDsLen, &UpdatedsLenReq, DeletedIDs, DeletedIDsLen, DeletedLenReq, NULL, 0, 0); if (AEE_SUCCESS != nErr) { // Handle error here. Be sure to handle pim_IRecordStore_ESTALESEQNUM // error code. if (pim_IRecordStore_ESTALESEQNUM == nErr) { // Provide valid input for UnchangedIDs and compare them with previous // snapshot of record IDs to find out deleted records. } } SeqNum = CurrentSeqNum; // Update your baseline // Remember to deallocate using IENV_FREEIF() after done using AddedIDs. nErr = IEnv_ErrMallocNoZI(piEnv, AddedIDsLenReq, (void **)&AddedIDs); if (AEE_SUCCESS != nErr) { // Handle error here. } AddedIDsLen = AddedIDsLenReq; // Remember to deallocate using IENV_FREEIF() after done using UpdatedIDs. nErr = IEnv_ErrMallocNoZI(piEnv, UpdatedIDsLenReq, (void **)&UpdatedIDs); if (AEE_SUCCESS != nErr) { // Handle error here. } UpdatedIDsLen = UpdatedIDsLenReq; // Remember to deallocate using IENV_FREEIF() after done using DeletedIDs. nErr = IEnv_ErrMallocNoZI(piEnv, DeletedIDsLenReq, (void **)&DeletedIDs); if (AEE_SUCCESS != nErr) { // Handle error here. } DeletedIDsLen = DeletedIDsLenReq; nErr = pim_IRecordStore_GetChangesSince(piCallHistoryRecordStore, &CurrentSeqNum, SeqNum, AddedIDs, AddedIDsLen, &AddedIDsLenReq, UpdatedIDs, UpdatedIDsLen, &UpdatedsLenReq, DeletedIDs, DeletedIDsLen, DeletedLenReq, NULL, 0, 0); if (AEE_SUCCESS != nErr) { // Handle error here. Be sure to handle pim_IRecordStore_ESTALESEQNUM // error code. if (pim_IRecordStore_ESTALESEQNUM == nErr) { // Provide valid input for UnchangedIDs and compare them with previous // snapshot of record IDs to find out deleted records. } } nErr = pim_IRecordStore_OnChange(piCallHistoryRecordStore, piSignal, pim_IRecordStore_Action_Commit, &piQI); if (AEE_SUCCESS != nErr) { // Handle error here. } // For efficiency reasons, it is recommened that SeqNum and record IDs be // stored in persistent storage so that the next time the application is // started, these values can be used as the baseline. Additionally, the following sequence diagram depicts how a client may use the sequence number information to efficiently find out what changes occurred in the call history record store. Application System | | | | 1) |--> pim_IRecordStore_GetChangesSince() with baseline seq num ---->| |--- Baseline seq num should be either read from persistent storage -| |--- or can be 0 for the very first time. It is recommended that ---| |--- sequence number and record IDs be stored in persistent storage -| |--- so that the application can use those values for their most ---| |--- recent baseline snapshot to enhance efficiency. ---| 2) |<-- Current seq num and snapshot of current record identifiers <----| |--- Client remembers new seq num obtained from this call to use ---| |--- in next call to pim_IRecordStore_GetChangesSince() ---| |--- Client remembers snapshot of record identifiers e.g. {1,2,3} ---| 3) |-----------------> pim_IRecordStore_OnChange() ------------------->| | . | | . | | . | 4) |<---------- Call history got changed and Signal is set <-----------| 5) |--> pim_IRecordStore_GetChangesSince() with seq num from step 2 --->| 6) |<-- Current seq num and snapshot of current record identifiers <----| |--- Client obtains list of added, updated and deleted record IDs. --| |--- Client remembers snapshot of record identifiers based on -------| |--- list of added and updated IDs. e.g. {1,3,4,5} ---| 7) |---------> pim_IRecordStore_GetRecord() with record IDs 1,3,4,5 --->| |--- Client goes to sleep/gets terminated. ---| | . | | . | | . | |--- Client wakes up. ---| 8) |--> pim_IRecordStore_GetChangesSince() with seq num from step 5 --->| 9) |<---- pim_IRecordStore_ESTALESEQNUM! Maybe many changes have ---| |--- happened to callhistory. <----| |--- Client prepares for "slow sync" by providing valid values for --| |--- AddedIDs, UpdatedIDs and UnchangedIDs. ---| 10) |--> pim_IRecordStore_GetChangesSince() with valid AddedIDs, ---| |--- UpdatedIDs and UnchangedIDs. --------------->| 11) |<-- Current seq num and snapshot of current record identifiers <----| |--- Client compares added, updated and unchanged record IDs with ---| |--- previous snapshot to find out records that were deleted. ---| |--- Client remembers new seq num obtained from this call to use ---| |--- in next call to pim_IRecordStore_GetChangesSince() ---|
Interface