ADD_DEFINITIONS( -DFEATURE_OPTIONAL_MSG_PORT )
ENDIF(ENABLE_OPTIONAL_MSG_PORT)
+IF(WITH_EBOOK)
+ # Replaces the default contacts-service2.
+ MESSAGE(STATUS "Contacts API using Evolution Data Server libebook")
+ ADD_DEFINITIONS( -DFEATURE_EBOOK )
+ENDIF(WITH_EBOOK)
+
IF(ENABLE_OPTIONAL_SYSINFO_TEL_SIM_MNGT)
MESSAGE(STATUS "System-info SIM management API Enabled")
ADD_DEFINITIONS( -DENABLE_OPTIONAL_SYSINFO_TEL_SIM_MNGT )
+* Tue Nov 19 2013 Patrick Ohly <patrick.ohly@intel.com> accepted/tizen/20131118.182136@e0defdb
+- implement Contacts API using Evolution Data Server (TIVI-1407)
+
* Tue Nov 19 2013 Rusty Lynch <rusty.lynch@intel.com> accepted/tizen/20131118.182136@7cc7b09
- message-port: Add explicit check for capi-appfw-app-manager
- Fix TIVI-2057 : Set request mode for installation / uninstallation to quiet mode.
%bcond_with wrt_option_sysinfo_tel_sim_mngt
%bcond_with wrt_option_sysinfo_cellular_network_mngt
%bcond_with wrt_option_msg_port
+%bcond_with wrt_option_eds
Name: wrt-plugins-tizen
Summary: JavaScript plugins for WebRuntime
Version: 0.4.68
BuildRequires: pkgconfig(mm-fileinfo)
BuildRequires: pkgconfig(libpcrecpp)
BuildRequires: pkgconfig(calendar-service2)
+%if %{with wrt_option_eds}
+BuildRequires: pkgconfig(libebook-1.2)
+%else
BuildRequires: pkgconfig(contacts-service2)
+%endif
+%if %{with wrt_option_call_history}
+BuildRequires: pkgconfig(contacts-service2)
+%endif
BuildRequires: pkgconfig(msg-service)
BuildRequires: pkgconfig(email-service)
BuildRequires: pkgconfig(accounts-svc)
%if %{with wrt_option_msg_port}
-DENABLE_OPTIONAL_MSG_PORT=YES \
%endif
+%if %{with wrt_option_eds}
+ -DWITH_EBOOK=YES \
+%endif
. -DCMAKE_INSTALL_PREFIX=%{_prefix} -DDPL_LOG="ON" -DENABLE_TIME_TRACER="OFF"
make %{?jobs:-j%jobs}
using namespace WrtDeviceApis::Commons;
using namespace std;
-AddressBook::AddressBook(bool isUnified) :
+AddressBook::AddressBook(
+#ifdef FEATURE_EBOOK
+ EBookClientCXX &ebook
+#else
+ bool isUnified
+#endif
+ ) :
IAddressBook(),
+#ifdef FEATURE_EBOOK
+ m_ebook(ebook),
+#else
m_id(0),
+#endif
m_name("TEST_ADDRESS_BOOK"),
m_readOnly(false),
m_accountId(0),
- m_isUnifiedAddressBook(isUnified),
+ m_isUnifiedAddressBook(
+#ifdef FEATURE_EBOOK
+ false
+#else
+ isUnified
+#endif
+ ),
m_eventMapAcc(100)
{
LoggerD("entered");
+#ifdef FEATURE_EBOOK
+ // Initialize view. It will be activated only if the JS side asks
+ // to watch for changes.
+ EBookQueryCXX allItemsQuery(e_book_query_any_field_contains(""), TRANSFER_REF);
+ PlainGStr sexp(e_book_query_to_string (allItemsQuery.get()));
+ EBookClientView *view;
+ GErrorCXX gerror;
+ if (!e_book_client_get_view_sync(m_ebook, sexp, &view, NULL, gerror))
+ ThrowMsg(PlatformException, gerror.msg());
+ m_view.take(view);
+ m_view.connectSignal<void (EBookClientView *ebookview,
+ GSList *data)>("objects-added", boost::bind(&AddressBook::onContactsEDSContactsAddedOrUpdated,
+ this,
+ _2,
+ &AddressBook::onContactsSvcContactsAdded));
+ m_view.connectSignal<void (EBookClientView *ebookview,
+ GSList *data)>("objects-modified", boost::bind(&AddressBook::onContactsEDSContactsAddedOrUpdated,
+ this,
+ _2,
+ &AddressBook::onContactsSvcContactsUpdated));
+ m_view.connectSignal<void (EBookClientView *ebookview,
+ GSList *data)>("objects-removed", boost::bind(&AddressBook::onContactsEDSContactsRemoved,
+ this,
+ _2));
+ e_book_client_view_set_flags(m_view, E_BOOK_CLIENT_VIEW_FLAGS_NONE, gerror);
+ if (gerror)
+ ThrowMsg(PlatformException, gerror.msg());
+#endif
}
AddressBook::~AddressBook()
{
+#ifndef FEATURE_EBOOK
if(m_addressBookEmitters.size() != 0)
{
ContactsSvcChangeListenerManagerSingleton::Instance().unregisterContactsChangeListener(this);
}
+#endif
}
std::string AddressBook::getId() const
{
+#ifdef FEATURE_EBOOK
+ ESource *esource = e_client_get_source(E_CLIENT(m_ebook.get()));
+ const char *uid = e_source_get_uid(esource);
+ // Use "0" instead of real "system-address-book" UID for the
+ // default system address book, for compatibility with apps
+ // which (incorrectly) have that id hard-coded.
+ const char *id = strcmp(uid, "system-address-book") ? uid : "0";
+ return id;
+#else
if(m_isUnifiedAddressBook)
return string("");
return ContactUtility::intToStr(m_id);
+#endif
}
+#ifndef FEATURE_EBOOK
void AddressBook::setId(const std::string &value)
{
m_id = ContactUtility::strToInt(value);
}
+#endif
std::string AddressBook::getAccountId() const
{
{
LoggerD("entered");
- int errorCode = 0;
contacts_record_h contacts_record = NULL;
Try
string contactId = event->getId();
+#ifdef FEATURE_EBOOK
+ EContact *econtact;
+ GErrorCXX gerror;
+ if (!e_book_client_get_contact_sync(m_ebook, contactId.c_str(), &econtact, NULL, gerror)) {
+ ThrowMsg(NotFoundException, gerror.msg());
+ }
+ contacts_record.take(econtact);
+#else
+ int errorCode = 0;
int contactIdInt = ContactUtility::strToInt(contactId);
errorCode = contacts_db_get_record(_contacts_contact._uri, contactIdInt, &contacts_record);
if(addressBookId != m_id)
ThrowMsg(NotFoundException, "No contact in this address book.");
}
+#endif
ContactObjectP2AConverterPtr contactObjConverter(
- new ContactObjectP2AConverter(contacts_record, false));
+ new ContactObjectP2AConverter(contacts_record,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false));
ContactPtr contact = contactObjConverter->getAbstractContact();
event->setContact(contact);
event->setResult(false);
}
- if(contacts_record != NULL)
+ if(contacts_record)
contacts_record_destroy(contacts_record, true);
}
ContactObjectA2PConverterPtr contactObjConverter(NULL);
contacts_record = contactT->getPlatformContactObject();
- if(contacts_record == NULL)
+ if(!contacts_record)
{
contactObjConverter = ContactObjectA2PConverterPtr(
- new ContactObjectA2PConverter(contact, false) );
+ new ContactObjectA2PConverter(contact,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false) );
contacts_record = contactObjConverter->getPlatformContact();
}
else
{
contactObjConverter = ContactObjectA2PConverterPtr(
- new ContactObjectA2PConverter(contact, false, contacts_record) );
+ new ContactObjectA2PConverter(contact,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false, contacts_record) );
contacts_record = contactObjConverter->getPlatformContact();
}
- int contactId = 0;
if (!contacts_record)
{
LoggerE("Error during converting contact object");
ThrowMsg(PlatformException, "Error during converting contact object");
}
+#ifndef FEATURE_EBOOK
if(m_isUnifiedAddressBook)
errorCode = contacts_record_set_int(contacts_record, _contacts_contact.address_book_id, 0);
else
errorCode = contacts_record_set_int(contacts_record, _contacts_contact.address_book_id, m_id);
+#endif
+
if(errorCode != CONTACTS_ERROR_NONE)
{
LoggerE("error code : " << errorCode);
ThrowMsg(PlatformException, "Error during executing contacts_db_insert_record()");
}
+#ifdef FEATURE_EBOOK
+ char *uid;
+ GErrorCXX gerror;
+ if (!e_book_client_add_contact_sync(m_ebook, contacts_record, &uid, NULL, gerror)) {
+ ThrowMsg(PlatformException, gerror.msg());
+ }
+ e_contact_set(contacts_record, E_CONTACT_UID, uid);
+ g_free(uid);
+ // TODO? Retrieve REV and store in m_platformContact.
+
+ // Must have been saved exactly as requested, so no need to read from DB.
+ get_contacts_record = contacts_record;
+#else
+ int contactId = 0;
errorCode = contacts_db_insert_record(contacts_record, &contactId);
if(errorCode != CONTACTS_ERROR_NONE)
{
errorCode = contacts_db_get_record(_contacts_contact._uri, contactId, &get_contacts_record);
if(errorCode != CONTACTS_ERROR_NONE || get_contacts_record == NULL)
ThrowMsg(PlatformException, "No contact just inserted");
+#endif
ContactObjectP2AConverterPtr contactObjConverterForInserted(
- new ContactObjectP2AConverter(get_contacts_record, false));
+ new ContactObjectP2AConverter(get_contacts_record,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false));
ContactPtr insertedContact = contactObjConverterForInserted->getAbstractContact();
contact->copy(insertedContact);
event->setExceptionCode(ExceptionCodes::UnknownException);
}
- if(get_contacts_record != NULL)
+ if(get_contacts_record)
contacts_record_destroy(get_contacts_record, true);
}
LoggerD("entered");
int errorCode = 0;
- contacts_list_h contacts_list = NULL;
+ contacts_list_h contacts_list(NULL);
ContactArrayPtr contacts(NULL);
if(!event->getContactsIsSet())
DPL::SharedPtr<Contact> newContactT =
DPL::StaticPointerCast<Contact>(contact);
contacts_record = newContactT->getPlatformContactObject();
- if(contacts_record == NULL)
+ if(!contacts_record)
{
+#ifdef FEATURE_EBOOK
+ contacts_record.take(e_contact_new());
+ if(!contacts_record)
+ {
+ ThrowMsg(PlatformException, "Error during creating contact record");
+ }
+#else
errorCode = contacts_record_create(_contacts_contact._uri, &contacts_record);
if(errorCode != CONTACTS_ERROR_NONE)
{
ThrowMsg(PlatformException, "Error during creating contact record : " << errorCode);
}
+#endif
}
contactObjConverter = ContactObjectA2PConverterPtr(
- new ContactObjectA2PConverter(contact, false, contacts_record) );
+ new ContactObjectA2PConverter(contact,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false, contacts_record) );
contacts_record = contactObjConverter->getPlatformContact();
- if(contacts_record == NULL)
+ if(!contacts_record)
{
ThrowMsg(PlatformException, "Error during converting contact object");
}
+#ifndef FEATURE_EBOOK
if(m_isUnifiedAddressBook)
errorCode = contacts_record_set_int(contacts_record, _contacts_contact.address_book_id, 0);
else
errorCode = contacts_record_set_int(contacts_record, _contacts_contact.address_book_id, m_id);
+#endif
if(errorCode != CONTACTS_ERROR_NONE)
{
ThrowMsg(PlatformException, "Error during add address book : " << errorCode);
}
Catch(InvalidArgumentException)
{
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, true);
ThrowMsg(InvalidArgumentException, "Error during converting contact object");
}
Catch(PlatformException)
{
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, true);
ThrowMsg(PlatformException, "Error during converting contact object");
}
Catch(Exception)
{
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, true);
ThrowMsg(Exception, "Error during converting contact object");
KeySharePtrPair *keyPair = new KeySharePtrPair();
keyPair->key = m_eventMapAcc;
keyPair->addressBook = this;
+#ifdef FEATURE_EBOOK
+ errorCode = CONTACTS_ERROR_NONE;
+ if (contacts_list) {
+ e_book_client_add_contacts(m_ebook, contacts_list, NULL, contactsAddBatchResultCallback, keyPair);
+ } else {
+ // Don't rely on EDS handling empty lists, it doesn't
+ // invoke the callback in that case. Instead use an
+ // idle callback. We must not invoke the callback
+ // directly here, the event is not set up for it yet
+ // (see switchToManualAnswer()).
+ g_idle_add(contactsAddBatchIdleCallback, keyPair);
+ }
+#else
errorCode = contacts_db_insert_records_async(contacts_list, contactsAddBatchResultCallback, (void*)keyPair);
+#endif
if(errorCode != CONTACTS_ERROR_NONE)
{
delete keyPair;
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, true);
ThrowMsg(PlatformException, "Error during contacts_db_insert_records_async");
}
errorCode = contacts_list_destroy(contacts_list, true);
- contacts_list = NULL;
if(errorCode != CONTACTS_ERROR_NONE)
{
delete keyPair;
- if(contacts_list != NULL)
- contacts_list_destroy(contacts_list, true);
ThrowMsg(PlatformException, "Error during contacts_list_destroy");
}
Try
{
- int errorCode = 0;
-
DPL::SharedPtr<Contact> contactT =
DPL::StaticPointerCast<Contact>(contact);
ContactObjectA2PConverterPtr contactObjConverter(NULL);
contacts_record_h contacts_record = contactT->getPlatformContactObject();
- if(contacts_record == NULL)
+ if(!contacts_record)
{
contactObjConverter = ContactObjectA2PConverterPtr(
- new ContactObjectA2PConverter(contact, false) );
+ new ContactObjectA2PConverter(contact,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false) );
contacts_record = contactObjConverter->getPlatformContact();
}
else
{
contactObjConverter = ContactObjectA2PConverterPtr(
- new ContactObjectA2PConverter(contact, false, contacts_record) );
+ new ContactObjectA2PConverter(contact,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false, contacts_record) );
contacts_record = contactObjConverter->getPlatformContact();
}
ThrowMsg(PlatformException, "Error during converting contact object");
}
- errorCode = contacts_db_update_record(contacts_record);
+#ifdef FEATURE_EBOOK
+ GErrorCXX gerror;
+ if (!e_book_client_modify_contact_sync(m_ebook, contacts_record, NULL, gerror))
+ {
+ if (gerror.matches(E_BOOK_CLIENT_ERROR,
+ E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND))
+ ThrowMsg(NotFoundException, gerror.msg());
+ else
+ ThrowMsg(PlatformException, gerror.msg());
+ }
+#else
+ int errorCode = contacts_db_update_record(contacts_record);
if (errorCode == CONTACTS_ERROR_INVALID_PARAMETER)
ThrowMsg(NotFoundException, "Error during executing contacts_db_update_record()");
else if (errorCode == CONTACTS_ERROR_NO_DATA)
LoggerE("error code : " << errorCode);
ThrowMsg(PlatformException, "Error during executing contacts_db_update_record()");
}
+#endif
}
Catch (NotFoundException)
{
{
LoggerD("entered");
int errorCode = 0;
- contacts_list_h contacts_list = NULL;
+ contacts_list_h contacts_list(NULL);
ContactArrayPtr contacts(NULL);
if(!event->getContactsIsSet())
errorCode = contacts_list_create(&contacts_list);
if(errorCode != CONTACTS_ERROR_NONE)
{
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, false);
ThrowMsg(PlatformException, "Fail to create contacts_list_h");
DPL::SharedPtr<Contact> newContactT = DPL::StaticPointerCast<Contact>(contact);
contacts_record = newContactT->getPlatformContactObject();
- if(contacts_record == NULL)
+ if(!contacts_record)
{
+#ifdef FEATURE_EBOOK
+ EContact *econtact;
+ GErrorCXX gerror;
+ if (!e_book_client_get_contact_sync(m_ebook, contact->getId().c_str(), &econtact, NULL, gerror))
+ ThrowMsg(NotFoundException, "No contact");
+ contacts_record.take(econtact);
+#else
int contactIdInt = ContactUtility::strToInt(contact->getId());
errorCode = contacts_db_get_record(_contacts_contact._uri, contactIdInt, &contacts_record);
if(errorCode != CONTACTS_ERROR_NONE || contacts_record == NULL)
ThrowMsg(NotFoundException, "No contact");
+#endif
}
contactObjConverter = ContactObjectA2PConverterPtr(
- new ContactObjectA2PConverter(contact, false, contacts_record) );
+ new ContactObjectA2PConverter(contact,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false, contacts_record) );
contacts_record = contactObjConverter->getPlatformContact();
- if(contacts_record == NULL)
+ if(!contacts_record)
ThrowMsg(PlatformException, "Error during converting contact object");
errorCode = contacts_list_add(contacts_list, contacts_record);
}
Catch(NotFoundException)
{
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, false);
ThrowMsg(NotFoundException, "Error during converting contact object");
}
Catch(InvalidArgumentException)
{
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, false);
ThrowMsg(InvalidArgumentException, "Error during converting contact object");
}
Catch(PlatformException)
{
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, false);
ThrowMsg(PlatformException, "Error during converting contact object");
}
Catch(Exception)
{
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, false);
ThrowMsg(Exception, "Error during converting contact object");
KeySharePtrPair *keyPair = new KeySharePtrPair();
keyPair->key = m_eventMapAcc;
keyPair->addressBook = this;
+
+#ifdef FEATURE_EBOOK
+ errorCode = CONTACTS_ERROR_NONE;
+ if (contacts_list) {
+ e_book_client_modify_contacts(m_ebook, contacts_list, NULL, contactsUpdateBatchResultCallback, keyPair);
+ } else {
+ // See AddBatch...
+ g_idle_add(contactsUpdateBatchIdleCallback, keyPair);
+ }
+#else
errorCode = contacts_db_update_records_async(contacts_list, contactsUpdateBatchResultCallback, (void*)keyPair);
+#endif
if(errorCode != CONTACTS_ERROR_NONE)
{
delete keyPair;
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, false);
ThrowMsg(PlatformException, "Error during contacts_db_update_records_async");
}
errorCode = contacts_list_destroy(contacts_list, true);
- contacts_list = NULL;
if(errorCode != CONTACTS_ERROR_NONE)
{
delete keyPair;
- if(contacts_list != NULL)
- contacts_list_destroy(contacts_list, false);
ThrowMsg(PlatformException, "Error during contacts_list_destroy");
}
{
LoggerD("entered");
- int errorCode = 0;
Try
{
if(!event->getContactIdIsSet())
string contactIdStr = event->getContactId();
+#ifdef FEATURE_EBOOK
+ GErrorCXX gerror;
+ if (!e_book_client_remove_contact_by_uid_sync(m_ebook, contactIdStr.c_str(), NULL, gerror)) {
+ if (gerror.matches(E_BOOK_CLIENT_ERROR,
+ E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND))
+ ThrowMsg(NotFoundException, gerror.msg());
+ else
+ ThrowMsg(PlatformException, gerror.msg());
+ }
+#else
+ int errorCode = 0;
+
if(!ContactUtility::checkStrIsUInt(contactIdStr))
ThrowMsg(InvalidArgumentException, "Id is wrong" );
ThrowMsg(NotFoundException, "Error during executing contacts_db_delete_record()");
else if (errorCode != CONTACTS_ERROR_NONE)
ThrowMsg(PlatformException, "Error during executing contacts_db_delete_record()");
+#endif
}
Catch (InvalidArgumentException)
{
if(!contactIds)
ThrowMsg(InvalidArgumentException, "Invalid contacts");
+#ifdef FEATURE_EBOOK
+ UIDList ids;
+#else
int *ids = new int[contactIds->size()];
// int *tmpIds = new int[contactIds->size()];
int count = 0;
+#endif
if(errorCode != CONTACTS_ERROR_NONE)
{
Try
{
+#ifdef FEATURE_EBOOK
+ ids.push_front(g_strdup(contactIdStr.c_str()));
+#else
int contactId;
if(!ContactUtility::checkStrIsUInt(contactIdStr))
ids[count] = contactId;
// tmpIds[count] = contactId;
count++;
+#endif
}
Catch(Exception)
{
if(errorCode != CONTACTS_ERROR_NONE)
ThrowMsg(PlatformException, "contacts_db_get_count_with_query error : " << errorCode << " (" << __FUNCTION__ << ")");
- if(filter != NULL)
+ if(filter)
contacts_filter_destroy(filter);
- if(query != NULL)
+ if(query)
contacts_query_destroy(query);
if(contactIds->size() != (unsigned int)record_count)
KeySharePtrPair *keyPair = new KeySharePtrPair();
keyPair->key = m_eventMapAcc;
keyPair->addressBook = this;
+#ifdef FEATURE_EBOOK
+ errorCode = CONTACTS_ERROR_NONE;
+ if (ids) {
+ e_book_client_remove_contacts(m_ebook, ids, NULL, contactsRemoveBatchResultCallback, keyPair);
+ } else {
+ // See BatchAdd...
+ g_idle_add(contactsRemoveBatchIdleCallback, keyPair);
+ }
+#else
errorCode = contacts_db_delete_records_async(_contacts_contact._uri, ids, count, contactsRemoveBatchResultCallback, (void*)keyPair);
if(ids != NULL)
{
delete [] ids;
}
+#endif
/*
if(tmpIds != NULL)
{
{
LoggerD("entered");
- contacts_query_h query = NULL;
- contacts_filter_h filter = NULL;
- contacts_list_h contacts_list = NULL;
-
- ContactArrayPtr contacts = ContactArrayPtr(new ContactArray());
-
Try
{
- ContactSearchEnginePtr searchEngine(new ContactSearchEngine());
+ ContactSearchEnginePtr searchEngine(new ContactSearchEngine(
+#ifdef FEATURE_EBOOK
+ m_ebook
+#endif
+ ));
+#ifndef FEATURE_EBOOK
if(!m_isUnifiedAddressBook)
searchEngine->setAddressBookId(m_id);
+#endif
if(event->getFilterIsSet())
{
event->setExceptionCode(ExceptionCodes::PlatformException);
event->setResult(false);
}
-
- if(filter != NULL)
- contacts_filter_destroy(filter);
-
- if(query != NULL)
- contacts_query_destroy(query);
-
- if(contacts_list != NULL)
- contacts_list_destroy(contacts_list, true);
}
void AddressBook::OnRequestReceived(const EventAddressBookAddChangeListenerPtr &event)
{
LoggerD("Watch registered initially");
+#ifdef FEATURE_EBOOK
+ GErrorCXX gerror;
+ e_book_client_view_start(m_view, gerror);
+ if (gerror)
+ ThrowMsg(PlatformException, gerror.msg());
+#else
if(m_isUnifiedAddressBook)
ContactsSvcChangeListenerManagerSingleton::Instance().registerContactsChangeListener(this, -1);
else
ContactsSvcChangeListenerManagerSingleton::Instance().registerContactsChangeListener(this, m_id);
+#endif
}
m_addressBookEmitters.attach(emitter);
+#ifdef FEATURE_EBOOK
+ // We only use the former getWatchIdAndInc() in one place, so
+ // we might as well use a simpler local, static counter. As in
+ // getWatchIdAndInc() we don't use thread locking.
+ static int watchId;
+ long id = ++watchId;
+#else
long id = ContactsSvcChangeListenerManagerSingleton::Instance().getWatchIdAndInc();
+#endif
m_watchIdMap[id] = emitter->getId();
event->setId(id);
{
LoggerD("No watcher is registered. unsubscribing from contact service.");
+#ifdef FEATURE_EBOOK
+ GErrorCXX gerror;
+ e_book_client_view_stop(m_view, gerror);
+ if (gerror)
+ ThrowMsg(PlatformException, gerror.msg());
+#else
ContactsSvcChangeListenerManagerSingleton::Instance().unregisterContactsChangeListener(this);
+#endif
}
event->setResult(true);
{
LoggerD("entered");
- int errorCode = 0;
contacts_record_h contacts_record = NULL;
Try
if(!event->getIdIsSet())
ThrowMsg(InvalidArgumentException, "Invalid group");
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
+ int errorCode = 0;
string groupId = event->getId();
int groupIdInt = ContactUtility::strToInt(groupId);
event->setContactGroup(group);
event->setResult(true);
+#endif
}
Catch (NotFoundException)
event->setResult(false);
}
- if(contacts_record != NULL)
+ if(contacts_record)
contacts_record_destroy(contacts_record, true);
}
{
LoggerD("entered");
- int errorCode = 0;
-
contacts_record_h contacts_record = NULL;
ContactGroupPtr group(NULL);
Try
{
- errorCode = contacts_record_create(_contacts_group._uri, &contacts_record);
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
+ int errorCode = contacts_record_create(_contacts_group._uri, &contacts_record);
if(errorCode != CONTACTS_ERROR_NONE)
{
LoggerE("error code : " << errorCode);
event->setResult(true);
event->setExceptionCode(ExceptionCodes::None);
+#endif
}
Catch (PlatformException)
{
event->setExceptionCode(ExceptionCodes::UnknownException);
}
- if(contacts_record != NULL)
+ if(contacts_record)
contacts_record_destroy(contacts_record, true);
}
{
LoggerD("entered");
- int errorCode = 0;
-
contacts_record_h contacts_record = NULL;
ContactGroupPtr group(NULL);
Try
{
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
int id = ContactUtility::strToInt(group->getId());
- errorCode = contacts_db_get_record(_contacts_group._uri, id, &contacts_record);
+ int errorCode = contacts_db_get_record(_contacts_group._uri, id, &contacts_record);
if (errorCode == CONTACTS_ERROR_INVALID_PARAMETER)
ThrowMsg(NotFoundException, "Error during executing contacts_db_get_record()");
else if (errorCode != CONTACTS_ERROR_NONE)
event->setResult(true);
event->setExceptionCode(ExceptionCodes::None);
+#endif
}
Catch (NotFoundException)
{
event->setExceptionCode(ExceptionCodes::PlatformException);
}
- if(contacts_record != NULL)
+ if(contacts_record)
contacts_record_destroy(contacts_record, true);
return;
{
LoggerD("entered");
- int errorCode = 0;
Try
{
if(!event->getContactGroupIdIsSet())
if(!ContactUtility::checkStrIsUInt(groupIdStr))
ThrowMsg(InvalidArgumentException, "wrong" );
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
int groupId = ContactUtility::strToInt(groupIdStr);
if(!m_isUnifiedAddressBook)
{
contacts_record_h contacts_record = NULL;
- errorCode = contacts_db_get_record(_contacts_group._uri, groupId, &contacts_record);
+ int errorCode = contacts_db_get_record(_contacts_group._uri, groupId, &contacts_record);
if(errorCode != CONTACTS_ERROR_NONE || contacts_record == NULL)
ThrowMsg(PlatformException, "No group");
ThrowMsg(PlatformException, "Contact is not a member of this address book.");
}
- errorCode = contacts_db_delete_record(_contacts_group._uri, groupId);
+ int errorCode = contacts_db_delete_record(_contacts_group._uri, groupId);
if(errorCode == CONTACTS_ERROR_INVALID_PARAMETER)
ThrowMsg(NotFoundException, "Error during executing contacts_db_delete_record()");
else if (errorCode != CONTACTS_ERROR_NONE)
event->setResult(true);
event->setExceptionCode(ExceptionCodes::None);
+#endif
}
Catch (InvalidArgumentException)
{
{
LoggerD("entered");
- int errorCode = 0;
-
ContactGroupArrayPtr groups(new ContactGroupArray());
- contacts_list_h groups_list = NULL;
+ contacts_list_h groups_list(NULL);
Try
{
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
+ int errorCode = 0;
if(m_isUnifiedAddressBook)
{
event->setContactGroups(groups);
event->setResult(true);
-
+#endif
}
Catch (NotFoundException)
{
event->setResult(false);
}
- if(groups_list != NULL)
+ if(groups_list)
contacts_list_destroy(groups_list, true);
}
+#ifdef FEATURE_EBOOK
+void AddressBook::onContactsEDSContactsAddedOrUpdated(GSList *data, void (AddressBook::*onSvc)(ContactArrayPtr &))
+{
+ GListCXX<EContact, GSList, NoopDestructor<EContact>, false> econtacts(data);
+ ContactArrayPtr contacts(new ContactArray);
+
+ BOOST_FOREACH (EContact *econtact, econtacts) {
+ Try {
+ ContactObjectP2AConverterPtr contactObjConverter(new ContactObjectP2AConverter(contacts_record_h(econtact, ADD_REF),
+ m_ebook,
+ false) );
+ contacts->push_back(contactObjConverter->getAbstractContact());
+ } Catch(Exception)
+ {
+ LoggerE("Fail error on converting contact to abs contact : " << _rethrown_exception.GetMessage());
+ }
+ }
+ (this->*onSvc)(contacts);
+}
+
+void AddressBook::onContactsEDSContactsRemoved(GSList *data)
+{
+ GListCXX<char, GSList, NoopDestructor<char>, false> uids(data);
+ StringArrayPtr contactIds(new StringArray);
+
+ BOOST_FOREACH (char *uid, uids) {
+ contactIds->push_back(uid);
+ }
+ onContactsSvcContactsRemoved(contactIds);
+}
+
+
+#endif
+
void AddressBook::onContactsSvcContactsAdded(ContactArrayPtr &contacts)
{
EventInfoAddressBookChangeAddedPtr contactsAdded(new EventInfoAddressBookChangeAdded());
m_addressBookEmitters.emit(listener);
}
-void AddressBook::contactsAddBatchResultCallback(int error, int *ids, unsigned int count, void *user_data)
+#ifdef FEATURE_EBOOK
+gboolean AddressBook::contactsAddBatchIdleCallback(void *user_data)
+{
+ KeySharePtrPair *keyPair = (KeySharePtrPair*)user_data;
+
+ long key = keyPair->key;
+ AddressBook *addressBook = keyPair->addressBook;
+
+ delete keyPair;
+
+ addressBook->contactsAddBatchResultCallback(NULL, NULL, key);
+
+ // Not again.
+ return false;
+}
+
+gboolean AddressBook::contactsUpdateBatchIdleCallback(void *user_data)
+{
+ KeySharePtrPair *keyPair = (KeySharePtrPair*)user_data;
+
+ long key = keyPair->key;
+ AddressBook *addressBook = keyPair->addressBook;
+
+ delete keyPair;
+
+ addressBook->contactsUpdateBatchResultCallback(NULL, key);
+
+ // Not again.
+ return false;
+}
+
+gboolean AddressBook::contactsRemoveBatchIdleCallback(void *user_data)
+{
+ KeySharePtrPair *keyPair = (KeySharePtrPair*)user_data;
+
+ long key = keyPair->key;
+ AddressBook *addressBook = keyPair->addressBook;
+
+ delete keyPair;
+
+ addressBook->contactsRemoveBatchResultCallback(NULL, key);
+
+ // Not again.
+ return false;
+}
+#endif
+
+void AddressBook::contactsAddBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ GObject *ebook, GAsyncResult *res,
+#else
+ int error, int *ids, unsigned int count,
+#endif
+ void *user_data)
{
LoggerD("entered");
if(user_data == NULL)
delete keyPair;
+#ifdef FEATURE_EBOOK
+ GSList *ids;
+ GErrorCXX gerror;
+ if (e_book_client_add_contacts_finish((EBookClient *)ebook, res, &ids, gerror)) {
+ addressBook->contactsAddBatchResultCallback(NULL, UIDList(ids), key);
+ } else {
+ addressBook->contactsAddBatchResultCallback(gerror.msg(), NULL, key);
+ }
+#else
addressBook->contactsAddBatchResultCallback(error, ids, count, key);
+#endif
}
-void AddressBook::contactsAddBatchResultCallback(int error, int *ids, unsigned int count, long key)
+void AddressBook::contactsAddBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ const char *error, const UIDList &ids,
+#else
+ int error, int *ids, unsigned int count,
+#endif
+ long key)
{
EventAddressBookAddBatchPtr event;
event = iter->second;
m_addBatchEventMap.erase(iter);
- if(error != CONTACTS_ERROR_NONE)
+ if(error !=
+#ifdef FEATURE_EBOOK
+ NULL
+#else
+ CONTACTS_ERROR_NONE
+#endif
+ )
{
LoggerE("contacts_db_insert_result_cb gives error : " << error);
event->setResult(false);
ContactArrayPtr contacts = event->getContacts();
#endif
+#ifdef FEATURE_EBOOK
+ unsigned int i;
+ UIDList::const_iterator it;
+ for (it = ids.begin(), i=0;
+ it != ids.end();
+ ++i, ++it)
+#else
for(unsigned int i=0; i<count; i++)
+#endif
{
+#ifdef FEATURE_EBOOK
+ EContact *econtact;
+ GErrorCXX gerror;
+ if (!e_book_client_get_contact_sync(m_ebook, *it, &econtact, NULL, gerror)) {
+ LoggerD("Fail e_book_client_get_contact_sync: " << gerror.msg());
+ continue;
+ }
+ contacts_record_h contacts_record(econtact, TRANSFER_REF);
+#else
int errorCode = 0;
int contactId = ids[i];
+
contacts_record_h contacts_record = NULL;
errorCode = contacts_db_get_record(_contacts_contact._uri, contactId, &contacts_record);
LoggerD("Fail contacts_db_get_record error _contacts_contact._uri : " << errorCode);
continue;
}
+#endif
#if 0
ContactPtr absContact(NULL);
{
#if 0
ContactObjectP2AConverterPtr contactObjConverter(
- new ContactObjectP2AConverter(contacts_record, false) );
+ new ContactObjectP2AConverter(contacts_record,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false) );
#else
ContactObjectP2AConverterPtr contactObjConverter(
- new ContactObjectP2AConverter(contacts_record, false, absContact) );
+ new ContactObjectP2AConverter(contacts_record,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false, absContact) );
#endif
absContact = contactObjConverter->getAbstractContact();
}
contacts->push_back(absContact);
#endif
- if(contacts_record != NULL)
+ if(contacts_record)
contacts_record_destroy(contacts_record, true);
}
EventRequestReceiver<EventAddressBookAddBatch>::ManualAnswer(event);
}
-void AddressBook::contactsUpdateBatchResultCallback(int error, void *user_data)
+void AddressBook::contactsUpdateBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ GObject *ebook, GAsyncResult *res,
+#else
+ int error,
+#endif
+ void *user_data)
{
LoggerD("entered");
delete keyPair;
+#ifdef FEATURE_EBOOK
+ GErrorCXX gerror;
+ const char *error =
+ e_book_client_modify_contacts_finish((EBookClient *)ebook, res, gerror) ?
+ NULL :
+ gerror.msg();
+#endif
addressBook->contactsUpdateBatchResultCallback(error, key);
}
-void AddressBook::contactsUpdateBatchResultCallback(int error, long key)
+void AddressBook::contactsUpdateBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ const char *error,
+#else
+ int error,
+#endif
+ long key)
{
EventAddressBookUpdateBatchPtr event;
event = iter->second;
m_updateBatchEventMap.erase(iter);
- if(error != CONTACTS_ERROR_NONE)
+ if(error !=
+#ifdef FEATURE_EBOOK
+ NULL
+#else
+ CONTACTS_ERROR_NONE
+#endif
+ )
{
LoggerE("contacts_db_result_cb gives error : " << error);
event->setResult(false);
EventRequestReceiver<EventAddressBookUpdateBatch>::ManualAnswer(event);
}
-void AddressBook::contactsRemoveBatchResultCallback(int error, void *user_data)
+void AddressBook::contactsRemoveBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ GObject *ebook, GAsyncResult *res,
+#else
+ int error,
+#endif
+ void *user_data)
{
LoggerD("entered");
delete keyPair;
+#ifdef FEATURE_EBOOK
+ GErrorCXX gerror;
+ const char *error =
+ e_book_client_remove_contacts_finish((EBookClient *)ebook, res, gerror) ?
+ NULL :
+ gerror.msg();
+#endif
addressBook->contactsRemoveBatchResultCallback(error, key);
}
-void AddressBook::contactsRemoveBatchResultCallback(int error, long key)
+void AddressBook::contactsRemoveBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ const char *error,
+#else
+ int error,
+#endif
+ long key)
{
EventAddressBookRemoveBatchPtr event;
event = iter->second;
m_removeBatchEventMap.erase(iter);
- if(error != CONTACTS_ERROR_NONE)
+ if(error !=
+#ifdef FEATURE_EBOOK
+ NULL
+#else
+ CONTACTS_ERROR_NONE
+#endif
+ )
{
LoggerE("contacts_db_result_cb gives error : " << error);
event->setResult(false);
#include <Commons/Emitters.h>
#include "IAddressBook.h"
#include "IContact.h"
+#include <contacts.h>
#include "ContactsSvcChangeListenerManager.h"
class AddressBook : public IAddressBook, public IContactsSvcContactsChangeListener
{
private:
+#ifdef FEATURE_EBOOK
+ EBookClientCXX m_ebook;
+ EBookClientViewCXX m_view;
+#else
int m_id;
+#endif
std::string m_name;
bool m_readOnly;
int m_accountId;
bool m_isUnifiedAddressBook;
public:
+#ifdef FEATURE_EBOOK
+ explicit AddressBook(EBookClientCXX &ebook);
+#else
explicit AddressBook(bool isUnified);
+#endif
virtual ~AddressBook();
virtual std::string getId() const;
+#ifndef FEATURE_EBOOK
virtual void setId(const std::string &value);
void setId(const int &value) { m_id = value; }
+#endif
virtual std::string getName() const { return m_name; }
virtual void setName(const std::string &value) { m_name = value; }
virtual bool getReadOnly() const { return m_readOnly; }
virtual void onContactsSvcContactsUpdated(ContactArrayPtr &contacts);
virtual void onContactsSvcContactsRemoved(StringArrayPtr &contactIds);
+#ifdef FEATURE_EBOOK
+ void onContactsEDSContactsAddedOrUpdated(GSList *data, void (AddressBook::*onSvc)(ContactArrayPtr &));
+ void onContactsEDSContactsRemoved(GSList *data);
+#endif
+
private:
typedef WrtDeviceApis::Commons::Emitters<EventAddressBookChangeListenerEmitter> AddressBookChangedEmitter;
AddressBookChangedEmitter m_addressBookEmitters;
typedef std::map<long, EventAddressBookChangeListenerEmitter::IdType> WatchIdMap;
WatchIdMap m_watchIdMap;
- static void contactsAddBatchResultCallback(int error, int *ids, unsigned int count, void *user_data);
- void contactsAddBatchResultCallback(int error, int *ids, unsigned int count, long key);
-
- static void contactsUpdateBatchResultCallback(int error, void *user_data);
- void contactsUpdateBatchResultCallback(int error, long key);
-
- static void contactsRemoveBatchResultCallback(int error, void *user_data);
- void contactsRemoveBatchResultCallback(int error, long key);
+#ifdef FEATURE_EBOOK
+ static gboolean contactsAddBatchIdleCallback(void *user_data);
+ static gboolean contactsUpdateBatchIdleCallback(void *user_data);
+ static gboolean contactsRemoveBatchIdleCallback(void *user_data);
+#endif
+ static void contactsAddBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ GObject *ebook, GAsyncResult *res,
+#else
+ int error, int *ids, unsigned int count,
+#endif
+ void *user_data);
+ void contactsAddBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ const char *error, const UIDList &ids,
+#else
+ int error, int *ids, unsigned int count,
+#endif
+ long key);
+
+ static void contactsUpdateBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ GObject *ebook, GAsyncResult *res,
+#else
+ int error,
+#endif
+ void *user_data);
+ void contactsUpdateBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ const char *error,
+#else
+ int error,
+#endif
+ long key);
+
+ static void contactsRemoveBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ GObject *ebook, GAsyncResult *res,
+#else
+ int error,
+#endif
+ void *user_data);
+ void contactsRemoveBatchResultCallback(
+#ifdef FEATURE_EBOOK
+ const char *error,
+#else
+ int error,
+#endif
+ long key);
struct KeySharePtrPair
{
SET(TARGET_IMPL_NAME ${contact_impl})
SET(TARGET_CONFIG_NAME ${contact_config})
-PKG_CHECK_MODULES(platform_pkgs_contact REQUIRED contacts-service2 libpcrecpp)
+IF(WITH_EBOOK)
+ PKG_CHECK_MODULES(platform_pkgs_contact REQUIRED libebook-1.2 libpcrecpp)
+ INCLUDE_DIRECTORIES(contacts2ebook)
+ELSE(WITH_EBOOK)
+ PKG_CHECK_MODULES(platform_pkgs_contact REQUIRED contacts-service2 libpcrecpp)
+ENDIF(WITH_EBOOK)
ADD_DEFINITIONS("-fvisibility=hidden")
Contact::~Contact()
{
- if (m_platformContactObjectList != NULL)
+ if (m_platformContactObjectList)
contacts_list_destroy(m_platformContactObjectList, true);
if(numbersJSObjIsSet()){
string Contact::convertToString(const string &format)
{
LoggerD("entered");
- int errorCode = 0;
- char *vcard_stream = NULL;
if(!format.empty() && format != "VCARD_30")
ThrowMsg(ConversionException, "format must be 'VCARD_30'");
contacts_record_h contacts_record = NULL;
Try {
- contactObjConverter = ContactObjectA2PConverterPtr(new ContactObjectA2PConverter(thisObj, true) );
+ contactObjConverter = ContactObjectA2PConverterPtr(new ContactObjectA2PConverter(thisObj,
+#ifdef FEATURE_EBOOK
+ EBookClientCXX(),
+#endif
+ true) );
contacts_record = contactObjConverter->getPlatformContact();
} Catch (Exception) {
ThrowMsg(PlatformException, "Fail to extract contact to platform object.");
}
- errorCode = contacts_vcard_make_from_contact(contacts_record, &vcard_stream);
+#ifdef FEATURE_EBOOK
+ PlainGStr vcard(e_vcard_to_string(E_VCARD(contacts_record.get()), EVC_FORMAT_VCARD_30));
+ string result(vcard);
+#else
+ char *vcard_stream = NULL;
+ int errorCode = contacts_vcard_make_from_contact(contacts_record, &vcard_stream);
if(errorCode != CONTACTS_ERROR_NONE)
ThrowMsg(PlatformException, "Fail to convert to vCard.");
string result((char *)vcard_stream);
free(vcard_stream);
+#endif
return result;
}
void Contact::setContactFromString(const std::string &vObjectStr)
{
LoggerD("entered");
+#ifdef FEATURE_EBOOK
+ contacts_record_h contacts_record(e_contact_new_from_vcard(vObjectStr.c_str()), TRANSFER_REF);
+ contacts_list_h contacts_list;
+ contacts_list.push_front(contacts_record.ref());
+#else
int errorCode = 0;
const char *vcard_stream = vObjectStr.c_str();
- contacts_list_h contacts_list = NULL;
+ contacts_list_h contacts_list(NULL);
errorCode = contacts_vcard_parse_to_contacts(vcard_stream, &contacts_list);
if(errorCode == CONTACTS_ERROR_INVALID_PARAMETER)
ThrowMsg(InvalidArgumentException, "Invalid vCard string.");
contacts_list_destroy(contacts_list, true);
ThrowMsg(InvalidArgumentException, "Invalid vCard string. (3)");
}
+#endif
ContactObjectP2AConverterPtr contactObjConverter(NULL);
Try {
ContactPtr thisObj = SharedFromThis();
- contactObjConverter = ContactObjectP2AConverterPtr(new ContactObjectP2AConverter(contacts_record, true, thisObj) );
+ contactObjConverter = ContactObjectP2AConverterPtr(new ContactObjectP2AConverter(contacts_record,
+#ifdef FEATURE_EBOOK
+ EBookClientCXX(),
+#endif
+ true, thisObj) );
contactObjConverter->getAbstractContact();
} Catch (Exception) {
ThrowMsg(PlatformException, "Fail to extract contact from platform object.");
}
m_platformContactObject = contacts_record;
- m_platformContactObjectList = contacts_list;
+#ifdef FEATURE_EBOOK
+ // TODO: at some point figure out how we can allow std::swap
+ // with our contacts_list_h and then remove this ifdef.
+ m_platformContactObjectList.swap(contacts_list);
+#else
+ std::swap(m_platformContactObjectList, contacts_list);
+#endif
}
void Contact::setNumbersJSObj(bool value, JSObjectRef initObj)
ContactManager::~ContactManager()
{
+#ifndef FEATURE_EBOOK
if(m_contactManagerEmitters.size() != 0)
{
ContactsSvcChangeListenerManagerSingleton::Instance().unregisterPersonsChangeListener(this);
}
+#endif
}
void ContactManager::OnRequestReceived(const EventContactManagerGetAddressBookPtr &event)
{
LoggerD("entered");
- int errorCode = 0;
contacts_record_h contacts_record = NULL;
Try {
string personId = event->getId();
+#ifdef FEATURE_EBOOK
+ ThrowMsg(UnsupportedException, "Person concept not supported.");
+#else
+
+ int errorCode = 0;
int personIdInt = ContactUtility::strToInt(personId);
errorCode = contacts_db_get_record(_contacts_person._uri, personIdInt, &contacts_record);
{
ThrowMsg(NotFoundException, "No person : " << errorCode);
}
+#endif
PersonPtr person = PersonPtr(new Person());
ContactsSvcObjectConverter::convertToAbstract(contacts_record, person);
event->setResult(false);
}
- if(contacts_record != NULL)
+ if(contacts_record)
contacts_record_destroy(contacts_record, true);
}
{
LoggerD("entered");
- int errorCode = 0;
-
contacts_record_h contacts_record = NULL;
PersonPtr person(NULL);
Try
{
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
+ int errorCode = 0;
+
int id = ContactUtility::strToInt(person->getId());
errorCode = contacts_db_get_record(_contacts_person._uri, id, &contacts_record);
if (errorCode == CONTACTS_ERROR_INVALID_PARAMETER)
LoggerE("error code : " << errorCode);
ThrowMsg(PlatformException, "Error during executing contacts_db_get_record()");
}
+#endif
ContactsSvcObjectConverter::convertToPlatform(person, contacts_record);
+#ifndef FEATURE_EBOOK
errorCode = contacts_db_update_record(contacts_record);
if (errorCode == CONTACTS_ERROR_INVALID_PARAMETER)
ThrowMsg(NotFoundException, "Error during executing contacts_db_update_record()");
LoggerE("error code : " << errorCode);
ThrowMsg(PlatformException, "Error during executing contacts_db_update_record()");
}
+#endif
event->setResult(true);
event->setExceptionCode(ExceptionCodes::None);
event->setExceptionCode(ExceptionCodes::PlatformException);
}
- if(contacts_record != NULL)
+ if(contacts_record)
contacts_record_destroy(contacts_record, true);
return;
{
LoggerD("entered");
int errorCode = 0;
- contacts_list_h contacts_list = NULL;
+ contacts_list_h contacts_list(NULL);
PersonArrayPtr persons(NULL);
if(!event->getPersonsIsSet())
errorCode = contacts_list_create(&contacts_list);
if(errorCode != CONTACTS_ERROR_NONE){
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, false);
ThrowMsg(PlatformException, "Fail to create contacts_list_h");
}
+#ifdef FEATURE_EBOOK
+ ThrowMsg(UnsupportedException, "Person concept not supported.");
+#endif
+
for(PersonArray::iterator i = persons->begin(); i != persons->end(); i++)
{
contacts_record_h contacts_record = NULL;
Try
{
+#ifndef FEATURE_EBOOK
int personIdInt = ContactUtility::strToInt(person->getId());
errorCode = contacts_db_get_record(_contacts_person._uri, personIdInt, &contacts_record);
if(errorCode != CONTACTS_ERROR_NONE)
{
ThrowMsg(NotFoundException, "No person");
}
+#endif
ContactsSvcObjectConverter::convertToPlatform(person, contacts_record);
}
Catch(NotFoundException)
{
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, false);
ThrowMsg(NotFoundException, "Error during converting contact object");
// LoggerE("Error during converting person object : " << _rethrown_exception.GetMessage());
}
Catch(PlatformException)
{
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, false);
ThrowMsg(NotFoundException, "Error during converting contact object");
// LoggerE("Error during converting person object : " << _rethrown_exception.GetMessage());
KeySharePtrPair *keyPair = new KeySharePtrPair();
keyPair->key = m_eventMapAcc;
keyPair->contactManager = this;
+#ifndef FEATURE_EBOOK
errorCode = contacts_db_update_records_async(contacts_list, personsUpdateBatchResultCallback, (void*)keyPair);
+#endif
if(errorCode != CONTACTS_ERROR_NONE)
{
delete keyPair;
- if(contacts_list != NULL)
+ if(contacts_list)
contacts_list_destroy(contacts_list, false);
ThrowMsg(PlatformException, "Error during contacts_db_update_records_async");
}
errorCode = contacts_list_destroy(contacts_list, true);
- contacts_list = NULL;
if(errorCode != CONTACTS_ERROR_NONE)
{
delete keyPair;
ThrowMsg(InvalidArgumentException, "wrong" );
}
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
int errorCode = contacts_db_delete_record(_contacts_person._uri, personId);
if(errorCode == CONTACTS_ERROR_INVALID_PARAMETER)
ThrowMsg(NotFoundException, "Error during executing contacts_db_delete_record()");
ThrowMsg(NotFoundException, "Error during executing contacts_db_delete_record()");
else if (errorCode != CONTACTS_ERROR_NONE)
ThrowMsg(PlatformException, "Error during executing contacts_db_delete_record()");
+#endif
event->setResult(true);
event->setExceptionCode(ExceptionCodes::None);
}
}
+#ifdef FEATURE_EBOOK
+ ThrowMsg(UnsupportedException, "Person concept not supported.");
+#else
KeySharePtrPair *keyPair = new KeySharePtrPair();
keyPair->key = m_eventMapAcc;
keyPair->contactManager = this;
m_removeBatchEventMap.insert(keyEventPair);
m_eventMapAcc++;
+#endif
}
void ContactManager::OnRequestReceived(const EventContactManagerRemoveBatchPtr &event)
LoggerD("entered");
Try {
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
PersonSearchEnginePtr searchEngine(new PersonSearchEngine());
if(event->getFilterIsSet())
event->setPersons(searchEngine->getResult());
event->setResult(true);
+#endif
} Catch (NotFoundException) {
LoggerE("Person doesn't exist : " << _rethrown_exception.GetMessage());
if(emitter == NULL)
ThrowMsg(InvalidArgumentException, "Invalid arguments.");
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
+
if(m_contactManagerEmitters.size() == 0)
{
LoggerD("Watch registered initially");
event->setId(id);
event->setResult(true);
+#endif
} Catch (NotFoundException) {
LoggerE("Person doesn't exist : " << _rethrown_exception.GetMessage());
m_watchIdMap.erase(id);
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
if(m_contactManagerEmitters.size() == 0)
{
LoggerD("No watcher is registered. unsubscribing from person service.");
ContactsSvcChangeListenerManagerSingleton::Instance().unregisterPersonsChangeListener(this);
}
+#endif
event->setResult(true);
*/
#include "ContactObjectA2PConverter.h"
+#include "ContactObjectP2AConverter.h"
#include <Commons/Exception.h>
#include "ContactUtility.h"
using namespace WrtDeviceApis::Commons;
using namespace std;
+#ifndef FEATURE_EBOOK
static const char *EMPTY_STRING = "";
+#endif
ContactObjectA2PConverter::ContactObjectA2PConverter(const ContactPtr &abstractContact,
+#ifdef FEATURE_EBOOK
+ EBookClientCXX ebook,
+#endif
bool forScratch) :
m_abstractContact(abstractContact),
+#ifdef FEATURE_EBOOK
+ m_ebook(ebook),
+#endif
m_platformContact(NULL),
m_forScratch(forScratch),
m_convertFinished(false),
}
ContactObjectA2PConverter::ContactObjectA2PConverter(const ContactPtr &abstractContact,
+#ifdef FEATURE_EBOOK
+ EBookClientCXX ebook,
+#endif
bool forScratch,
contacts_record_h platformContact) :
m_abstractContact(abstractContact),
+#ifdef FEATURE_EBOOK
+ m_ebook(ebook),
+#endif
m_platformContact(platformContact),
m_forScratch(forScratch),
m_convertFinished(false),
ContactObjectA2PConverter::~ContactObjectA2PConverter()
{
- if(m_platformContactOwnership && m_platformContact != NULL)
+ if(m_platformContactOwnership && m_platformContact)
{
contacts_record_destroy(m_platformContact, true);
m_platformContact = NULL;
{
LoggerD("enter");
- int errorCode = 0;
-
if(m_abstractContact == NULL)
{
LoggerE("Abstract contact object did not set");
ThrowMsg(InvalidArgumentException, "Abstract contact object did not set");
}
- if(m_platformContact == NULL)
+ if(!m_platformContact)
{
if(m_abstractContact->getIdIsSet() && (m_forScratch == false))
{
+#ifdef FEATURE_EBOOK
+ if (!m_ebook)
+ ThrowMsg(UnknownException, "cannot create new contact without address book");
+ EContact *econtact;
+ GErrorCXX gerror;
+ if (!e_book_client_get_contact_sync(m_ebook, m_abstractContact->getId().c_str(),
+ &econtact, NULL, gerror))
+ ThrowMsg(UnknownException, "e_book_client_get_contact_sync: " << gerror.msg());
+ m_platformContact.take(econtact);
+#else
int id = ContactUtility::strToInt(m_abstractContact->getId());
- errorCode = contacts_db_get_record(_contacts_contact._uri, id, &m_platformContact);
+ int errorCode = contacts_db_get_record(_contacts_contact._uri, id, &m_platformContact);
if(errorCode != CONTACTS_ERROR_NONE)
ThrowMsg(UnknownException, "error on contacts_db_get_record (errorCode:" << errorCode << ")");
+#endif
}
else
{
LoggerD("New platform object has been created");
- errorCode = contacts_record_create(_contacts_contact._uri, &m_platformContact);
+#ifdef FEATURE_EBOOK
+ m_platformContact.take(e_contact_new());
+#else
+ int errorCode = contacts_record_create(_contacts_contact._uri, &m_platformContact);
if(errorCode != CONTACTS_ERROR_NONE)
ThrowMsg(UnknownException, "error on contacts_record_create (errorCode:" << errorCode << ")");
+#endif
}
m_platformContactOwnership = true;
void ContactObjectA2PConverter::importBaseInfoValue()
{
+#ifndef FEATURE_EBOOK
int errorCode = 0;
contacts_record_h child_record = NULL;
char *oldValueStr = NULL;
string abstractValueStr;
string realPath;
+#endif
// Contact.photoURI
+#ifdef FEATURE_EBOOK
+ if (!m_abstractContact->getPhotoURIIsSet()) {
+ EContactFieldCXX<E_CONTACT_PHOTO>::set(m_platformContact, NULL);
+ } else {
+ EContactPhoto photo;
+ photo.type = E_CONTACT_PHOTO_TYPE_URI;
+ string uri = m_abstractContact->getPhotoURI();
+ photo.data.uri = const_cast<char *>(uri.c_str());
+ EContactFieldCXX<E_CONTACT_PHOTO>::set(m_platformContact, &photo);
+ }
+#else
if(!m_abstractContact->getPhotoURIIsSet() || m_abstractContact->getPhotoURI().empty())
{
errorCode = contacts_record_create(_contacts_image._uri, &child_record);
if(is_first)
contacts_record_add_child_record(m_platformContact, _contacts_contact.image, child_record);
}
+#endif
// Contact.ringtoneURI
+#ifndef FEATURE_EBOOK
newValueStr = NULL;
oldValueStr = NULL;
contacts_record_get_str_p(m_platformContact, _contacts_contact.ringtone_path, &oldValueStr);
ThrowMsg(PlatformException, "importing ringtoneURI E (err:" << errorCode);
}
}
+#endif
}
void ContactObjectA2PConverter::importNameValue()
{
+#ifndef FEATURE_EBOOK
int errorCode = 0;
contacts_record_h child_record = NULL;
+#endif
ContactNamePtr contactName = m_abstractContact->getName();
if(contactName == NULL ||
&& ( !contactName->getSuffixIsSet() || contactName->getSuffix().empty() )
&& ( !contactName->getPrefixIsSet() || contactName->getPrefix().empty() ) ) )
{
+#ifdef FEATURE_EBOOK
+ EContactFieldCXX<E_CONTACT_NAME>::set(m_platformContact, NULL);
+#else
errorCode = contacts_record_create(_contacts_name._uri, &child_record);
if(errorCode != CONTACTS_ERROR_NONE)
ThrowMsg(UnknownException, "creating name value A (errorCode:" << errorCode << ")");
contacts_record_add_child_record(m_platformContact, _contacts_contact.name, child_record);
+#endif
return;
}
+#ifdef FEATURE_EBOOK
+ EContactName name;
+ string first = contactName->getFirstName();
+ string middle = contactName->getMiddleName();
+ string last = contactName->getLastName();
+ string prefix = contactName->getPrefix();
+ string suffix = contactName->getSuffix();
+ name.given = contactName->getFirstNameIsSet() ? const_cast<char *>(first.c_str()) : NULL;
+ name.additional = contactName->getMiddleNameIsSet() ? const_cast<char *>(middle.c_str()) : NULL;
+ name.family = contactName->getLastNameIsSet() ? const_cast<char *>(last.c_str()) : NULL;
+ name.prefixes = contactName->getPrefixIsSet() ? const_cast<char *>(prefix.c_str()) : NULL;
+ name.suffixes = contactName->getSuffixIsSet() ? const_cast<char *>(suffix.c_str()) : NULL;
+ EContactFieldCXX<E_CONTACT_NAME>::set(m_platformContact, &name);
+#else
errorCode = contacts_record_get_child_record_at_p(m_platformContact, _contacts_contact.name, 0, &child_record);
if(errorCode != CONTACTS_ERROR_NONE || child_record == NULL)
{
}
contacts_record_add_child_record(m_platformContact, _contacts_contact.name, child_record);
+#endif
}
+#ifndef FEATURE_EBOOK
void ContactObjectA2PConverter::importNameValueToExistingValue(contacts_record_h child_record, ContactNamePtr &contactName)
{
int errorCode = 0;
}
}
}
+#endif
void ContactObjectA2PConverter::importCompanyList()
{
+#ifndef FEATURE_EBOOK
int errorCode = 0;
contacts_record_h child_record = NULL;
unsigned int record_count = 0;
child_record = NULL;
}
+#endif
ContactOrganizationArrayPtr organizations = m_abstractContact->getOrganizations();
if(organizations->size() == 0)
+ {
+#ifdef FEATURE_EBOOK
+ EContactFieldCXX<E_CONTACT_ORG>::set(m_platformContact, NULL);
+ EContactFieldCXX<E_CONTACT_ORG_UNIT>::set(m_platformContact, NULL);
+ EContactFieldCXX<E_CONTACT_TITLE>::set(m_platformContact, NULL);
+ EContactFieldCXX<E_CONTACT_ROLE>::set(m_platformContact, NULL);
+ EContactFieldCXX<E_CONTACT_ASSISTANT>::set(m_platformContact, NULL);
+#endif
return;
+ }
ContactOrganizationArray::iterator organizationsIter = organizations->begin();
for(; organizationsIter != organizations->end(); organizationsIter++)
{
ContactOrganizationPtr organization = *organizationsIter;
+#ifdef FEATURE_EBOOK
+ EContactFieldCXX<E_CONTACT_ORG>::setString(m_platformContact, organization->getName(), organization->getNameIsSet());
+ EContactFieldCXX<E_CONTACT_ORG_UNIT>::setString(m_platformContact, organization->getDepartment(), organization->getDepartmentIsSet());
+ EContactFieldCXX<E_CONTACT_TITLE>::setString(m_platformContact, organization->getTitle(), organization->getTitleIsSet());
+ EContactFieldCXX<E_CONTACT_ROLE>::setString(m_platformContact, organization->getRole(), organization->getRoleIsSet());
+ EContactFieldCXX<E_CONTACT_ASSISTANT>::setString(m_platformContact, organization->getAssistant(), organization->getAssistantIsSet());
+
+ // Only one ORG supported.
+ break;
+#else
child_record = NULL;
errorCode = contacts_record_create(_contacts_company._uri, &child_record);
contacts_record_destroy(child_record, true);
continue;
}
+#endif
}
}
void ContactObjectA2PConverter::importNoteList()
{
+#ifndef FEATURE_EBOOK
int errorCode = 0;
contacts_record_h child_record = NULL;
unsigned int record_count = 0;
child_record = NULL;
}
+#endif
StringArrayPtr notes = m_abstractContact->getNotes();
if(notes->size() == 0)
+ {
+#ifdef FEATURE_EBOOK
+ EContactFieldCXX<E_CONTACT_NOTE>::set(m_platformContact, NULL);
+#endif
return;
+ }
StringArray::iterator notesIter = notes->begin();
for(; notesIter != notes->end(); notesIter++)
{
string note = *notesIter;
+#ifdef FEATURE_EBOOK
+ EContactFieldCXX<E_CONTACT_NOTE>::set(m_platformContact, note.c_str());
+ // Only one note supported.
+ break;
+#else
child_record = NULL;
if(note.empty())
contacts_record_destroy(child_record, true);
continue;
}
+#endif
}
}
+#ifdef FEATURE_EBOOK
+
+template<class E, string (E::*getter)()> struct CopyStringValue
+{
+ typedef void (*Copy_t)(EVCard *vcard, EVCardAttribute *attribute, E &e);
+ static void copy(EVCard *vcard, EVCardAttribute *attribute, E &e)
+ {
+ string value = (e.*getter)();
+ e_vcard_append_attribute_with_value(vcard, attribute, value.c_str());
+ }
+};
+
+// Implements both importNumberList and importEmailList.
+template<class EArray, class T, class GT, class C>
+void importList(contacts_record_h &record, const EArray &array,
+ const char *property,
+ const Types<T> *types,
+ GT getTypes, // TArray (E::*getTypes)() const,
+ C copyValue
+ )
+{
+ // Remove all and add back.
+ e_vcard_remove_attributes(E_VCARD(record.get()), NULL, property);
+
+ BOOST_FOREACH (const typename EArray::value_type &entry, array) {
+ EVCardAttribute *attribute = e_vcard_attribute_new(NULL, property);
+ EVCardAttributeParam *parameter = e_vcard_attribute_param_new("TYPE");
+ BOOST_FOREACH (T typeEnum, *((*entry).*getTypes)()) {
+ for (const Types<T> *type = types;
+ type->typeString;
+ ++type) {
+ if (type->enumVal == typeEnum) {
+ e_vcard_attribute_param_add_value(parameter, type->typeString);
+ break;
+ }
+ }
+ }
+ e_vcard_attribute_add_param(attribute, parameter);
+ // Takes ownership of parameter and attribute instances.
+ copyValue(E_VCARD(record.get()), attribute, *entry);
+ }
+}
+#endif
+
+#ifdef FEATURE_EBOOK
+static void CopyNumber(EVCard *vcard, EVCardAttribute *attribute, const ContactPhoneNumber &number)
+{
+ string value = number.getNumber();
+ e_vcard_append_attribute_with_value(vcard, attribute, value.c_str());
+}
+#endif
+
void ContactObjectA2PConverter::importNumberList()
{
+#ifdef FEATURE_EBOOK
+ importList(m_platformContact, *m_abstractContact->getPhoneNumbers(),
+ EVC_TEL, EDSTelTypes,
+ &ContactPhoneNumber::getTypes,
+ CopyNumber);
+#else
int errorCode = 0;
contacts_record_h child_record = NULL;
unsigned int record_count = 0;
continue;
}
}
+#endif
}
+#ifdef FEATURE_EBOOK
+static void CopyEmail(EVCard *vcard, EVCardAttribute *attribute, const ContactEmailAddress &email)
+{
+ string value = email.getEmail();
+ e_vcard_append_attribute_with_value(vcard, attribute, value.c_str());
+}
+#endif
+
void ContactObjectA2PConverter::importEmailList()
{
+#ifdef FEATURE_EBOOK
+ importList(m_platformContact, *m_abstractContact->getEmails(),
+ EVC_EMAIL, EDSEmailTypes,
+ &ContactEmailAddress::getTypes,
+ CopyEmail);
+#else
int errorCode = 0;
contacts_record_h child_record = NULL;
unsigned int record_count = 0;
continue;
}
}
+#endif
}
void ContactObjectA2PConverter::importGrouprelList()
{
+#ifdef FEATURE_EBOOK
+ // Not supported.
+#else
int errorCode = 0;
contacts_record_h child_record = NULL;
unsigned int record_count = 0;
continue;
}
}
+#endif
}
void ContactObjectA2PConverter::importEventList()
{
+#ifdef FEATURE_EBOOK
+ // E_CONTACT_ANNIVERSARY not supported by mapping to JS,
+ // don't touch it.
+
+ if (m_abstractContact->getBirthdayIsSet()) {
+ tm birthdayTm = m_abstractContact->getBirthday();
+ EContactDate bday;
+ bday.year = birthdayTm.tm_year;
+ bday.month = birthdayTm.tm_mon;
+ bday.day = birthdayTm.tm_mday;
+ EContactFieldCXX<E_CONTACT_BIRTH_DATE>::set(m_platformContact, &bday);
+ } else {
+ EContactFieldCXX<E_CONTACT_BIRTH_DATE>::set(m_platformContact, NULL);
+ }
+#else
int errorCode = 0;
contacts_record_h child_record = NULL;
unsigned int record_count = 0;
importEventListBirthday();
importEventListAnniversary();
+#endif
}
+#ifndef FEATURE_EBOOK
void ContactObjectA2PConverter::importEventListBirthday()
{
int errorCode = 0;
}
}
}
+#endif
+
+#ifdef FEATURE_EBOOK
+static void CopyAddress(EVCard *vcard, EVCardAttribute *attribute, const ContactAddress &address)
+{
+ e_vcard_append_attribute_with_values(vcard, attribute,
+ address.getPostalCode().c_str(),
+ address.getRegion().c_str(),
+ address.getCity().c_str(),
+ address.getStreetAddress().c_str(),
+ address.getAdditionalInformation().c_str(),
+ address.getCountry().c_str(),
+ (void *)NULL);
+}
+#endif
void ContactObjectA2PConverter::importPostalList()
{
+#ifdef FEATURE_EBOOK
+ importList(m_platformContact, *m_abstractContact->getAddresses(),
+ EVC_ADR, EDSAdrTypes,
+ &ContactAddress::getTypes,
+ CopyAddress);
+#else
int errorCode = 0;
contacts_record_h child_record = NULL;
unsigned int record_count = 0;
continue;
}
}
+#endif
}
void ContactObjectA2PConverter::importWebAddrList()
{
+#ifdef FEATURE_EBOOK
+ // TODO as time permits.
+#else
int errorCode = 0;
contacts_record_h child_record = NULL;
unsigned int record_count = 0;
continue;
}
}
+#endif
}
void ContactObjectA2PConverter::importNicknameList()
{
+#ifdef FEATURE_EBOOK
+ // Not supported.
+#else
int errorCode = 0;
contacts_record_h child_record = NULL;
unsigned int record_count = 0;
continue;
}
}
+#endif
}
} // Contact
{
public:
ContactObjectA2PConverter(const ContactPtr &abstractContact,
- bool forScratch);
+#ifdef FEATURE_EBOOK
+ EBookClientCXX m_ebook,
+#endif
+ bool forScratch);
ContactObjectA2PConverter(const ContactPtr &abstractContact,
+#ifdef FEATURE_EBOOK
+ EBookClientCXX m_ebook,
+#endif
bool forScratch,
contacts_record_h platformContact);
virtual ~ContactObjectA2PConverter();
void importNicknameList();
ContactPtr m_abstractContact;
+#ifdef FEATURE_EBOOK
+ EBookClientCXX m_ebook;
+#endif
contacts_record_h m_platformContact;
bool m_forScratch;
bool m_convertFinished;
using namespace std;
ContactObjectP2AConverter::ContactObjectP2AConverter(contacts_record_h platformContact,
+#ifdef FEATURE_EBOOK
+ EBookClientCXX ebook,
+#endif
bool forScratch) :
m_platformContact(platformContact),
+#ifdef FEATURE_EBOOK
+ m_ebook(ebook),
+#endif
m_abstractContact(ContactPtr(NULL)),
m_forScratch(forScratch),
m_convertFinished(false)
}
ContactObjectP2AConverter::ContactObjectP2AConverter(contacts_record_h platformContact,
+#ifdef FEATURE_EBOOK
+ EBookClientCXX ebook,
+#endif
bool forScratch,
ContactPtr &abstractContact) :
m_platformContact(platformContact),
+#ifdef FEATURE_EBOOK
+ m_ebook(ebook),
+#endif
m_abstractContact(abstractContact),
m_forScratch(forScratch),
m_convertFinished(false)
{
//LoggerD("enter");
- if(m_platformContact == NULL)
+ if(!m_platformContact)
{
LoggerE("Platform contact object did not set");
ThrowMsg(InvalidArgumentException, "Platform contact object did not set");
void ContactObjectP2AConverter::exportBaseInfoValue()
{
+#ifndef FEATURE_EBOOK
int errorCode = 0;
+#endif
if(!m_forScratch)
{
+#ifdef FEATURE_EBOOK
+ PlainGStr buffer = EContactFieldCXX<E_CONTACT_UID>::get(m_platformContact);
+ const char *id = buffer;
+#else
int id = 0;
contacts_record_get_int(m_platformContact, _contacts_contact.id, &id);
+#endif
m_abstractContact->setId(id);
+#ifdef FEATURE_EBOOK
+ const char *addressBookId;
+ // Conversion might happen without an ebook, in which case we leave this empty.
+ if (m_ebook) {
+ ESource *source = e_client_get_source(E_CLIENT(m_ebook.get()));
+ addressBookId = e_source_get_uid(source);
+ } else {
+ addressBookId = "";
+ }
+ // Compatibility hack with contacts service
+ // implementation: id "0" == "system-address-book".
+ // Not required by API, but might be expected by apps
+ // anyway. Some WRT tests use "0".
+ if (!strcmp(addressBookId, "system-address-book")) {
+ addressBookId = "0";
+ }
+#else
int addressBookId = 0;
contacts_record_get_int(m_platformContact, _contacts_contact.address_book_id, &addressBookId);
+#endif
m_abstractContact->setAddressBookId(addressBookId);
+#ifdef FEATURE_EBOOK
+ // Fake a person ID by reusing the contact
+ // ID. Actually using it will fail, but perhaps having
+ // something set here will help apps which just access
+ // it for debugging purposes.
+ m_abstractContact->setPersonId(id);
+#else
int personId = 0;
contacts_record_get_int(m_platformContact, _contacts_contact.person_id, &personId);
m_abstractContact->setPersonId(personId);
-
+#endif
+
+#ifdef FEATURE_EBOOK
+ PlainGStr rev = EContactFieldCXX<E_CONTACT_REV>::get(m_platformContact);
+ GTimeVal timeval;
+ if (!rev || !rev[0] || !g_time_val_from_iso8601(rev, &timeval)) {
+ timeval.tv_sec = 0;
+ timeval.tv_usec = 0;
+ }
+ tm tm;
+ time_t time = timeval.tv_sec;
+ struct tm *changedTimeTm = gmtime_r(&time, &tm);
+#else
int changedTime = 0;
contacts_record_get_int(m_platformContact, _contacts_contact.changed_time, &changedTime);
time_t changedTimeT = static_cast<time_t>(changedTime);
struct tm *changedTimeTm = gmtime(&changedTimeT);
+#endif
m_abstractContact->setLastUpdated(*changedTimeTm);
+#ifdef FEATURE_EBOOK
+ m_abstractContact->setIsFavorite(false);
+#else
bool isFavorite = false;
errorCode = contacts_record_get_bool(m_platformContact, _contacts_contact.is_favorite, &isFavorite);
if(errorCode != CONTACTS_ERROR_NONE)
LoggerE("contacts_record_get_bool returned " << errorCode);
m_abstractContact->setIsFavorite(isFavorite);
+#endif
}
+#ifndef FEATURE_EBOOK
char *charValue = NULL;
-
+#endif
+
+#ifdef FEATURE_EBOOK
+ boost::shared_ptr<EContactPhoto> photo = EContactFieldCXX<E_CONTACT_PHOTO>::get(m_platformContact);
+ if (photo &&
+ photo->type == E_CONTACT_PHOTO_TYPE_URI && // EDS always stores as URI, but check anyway.
+ photo->data.uri &&
+ photo->data.uri[0])
+ m_abstractContact->setPhotoURI(photo->data.uri);
+ else
+ m_abstractContact->unsetPhotoURI();
+#else
contacts_record_get_str_p(m_platformContact, _contacts_contact.image_thumbnail_path, &charValue);
if (charValue)
m_abstractContact->setPhotoURI(ContactUtility::convertPathToUri(charValue));
if(m_abstractContact->getPhotoURIIsSet())
m_abstractContact->unsetPhotoURI();
}
+#endif
+#ifdef FEATURE_EBOOK
+ m_abstractContact->unsetRingtoneURI();
+#else
contacts_record_get_str_p(m_platformContact, _contacts_contact.ringtone_path, &charValue);
if (charValue)
m_abstractContact->setRingtoneURI(ContactUtility::convertPathToUri(charValue));
if(m_abstractContact->getRingtoneURIIsSet())
m_abstractContact->unsetRingtoneURI();
}
+#endif
if(!m_forScratch)
{
+#ifdef FEATURE_EBOOK
+ PlainGStr buffer = EContactFieldCXX<E_CONTACT_NAME_OR_ORG>::get(m_platformContact);
+ ContactNamePtr contactName = m_abstractContact->getName();
+ const char *displayname = buffer.get();
+ if(contactName == NULL)
+ {
+ contactName = ContactNamePtr(new ContactName());
+ m_abstractContact->setName(contactName);
+ }
+ if (displayname)
+ contactName->setDisplayName(displayname);
+ else
+ contactName->unsetDisplayName();
+#else
contacts_record_get_str_p(m_platformContact, _contacts_contact.display_name, &charValue);
if (charValue)
{
}
// else
// ThrowMsg(UnknownException, "converting base data (no display name)");
+#endif
}
}
void ContactObjectP2AConverter::exportNameValue()
{
+#ifdef FEATURE_EBOOK
+ boost::shared_ptr<EContactName> name = EContactFieldCXX<E_CONTACT_NAME>::get(m_platformContact);
+#else
int errorCode = 0;
contacts_record_h child_record = NULL;
if(errorCode != CONTACTS_ERROR_NONE && errorCode != CONTACTS_ERROR_NO_DATA)
ThrowMsg(UnknownException, "getting name value (err:" << errorCode << ")");
+#endif
+
+#ifdef FEATURE_EBOOK
+ if(!name)
+#else
if(child_record == NULL || errorCode == CONTACTS_ERROR_NO_DATA)
+#endif
{
//LoggerD("Platform contact don't have name value");
ContactNamePtr contactName = m_abstractContact->getName();
char *charValue = NULL;
+#ifdef FEATURE_EBOOK
+ charValue = name->given;
+#else
contacts_record_get_str_p(child_record, _contacts_name.first, &charValue);
+#endif
if (charValue)
contactName->setFirstName(charValue);
else
contactName->unsetFirstName();
}
+#ifdef FEATURE_EBOOK
+ charValue = name->additional;
+#else
contacts_record_get_str_p(child_record, _contacts_name.addition, &charValue);
+#endif
if (charValue)
contactName->setMiddleName(charValue);
else
contactName->unsetMiddleName();
}
+#ifdef FEATURE_EBOOK
+ charValue = name->family;
+#else
contacts_record_get_str_p(child_record, _contacts_name.last, &charValue);
+#endif
if (charValue)
contactName->setLastName(charValue);
else
contactName->unsetLastName();
}
+#ifdef FEATURE_EBOOK
+ charValue = name->prefixes;
+#else
contacts_record_get_str_p(child_record, _contacts_name.prefix, &charValue);
+#endif
if (charValue)
contactName->setPrefix(charValue);
else
contactName->unsetPrefix();
}
+#ifdef FEATURE_EBOOK
+ charValue = name->suffixes;
+#else
contacts_record_get_str_p(child_record, _contacts_name.suffix, &charValue);
+#endif
if (charValue)
contactName->setSuffix(charValue);
else
contactName->unsetSuffix();
}
+#ifdef FEATURE_EBOOK
+ charValue = NULL;
+#else
contacts_record_get_str_p(child_record, _contacts_name.phonetic_first, &charValue);
+#endif
if (charValue)
contactName->setPhoneticFirstName(charValue);
else
contactName->unsetPhoneticFirstName();
}
+#ifdef FEATURE_EBOOK
+ charValue = NULL;
+#else
contacts_record_get_str_p(child_record, _contacts_name.phonetic_middle, &charValue);
+#endif
if (charValue)
contactName->setPhoneticMiddleName(charValue);
else
contactName->unsetPhoneticMiddleName();
}
+#ifdef FEATURE_EBOOK
+ charValue = NULL;
+#else
contacts_record_get_str_p(child_record, _contacts_name.phonetic_last, &charValue);
+#endif
if (charValue)
contactName->setPhoneticLastName(charValue);
else
void ContactObjectP2AConverter::exportCompanyList()
{
+#ifndef FEATURE_EBOOK
int errorCode = 0;
unsigned int child_count = 0;
+#endif
if(m_abstractContact->getOrganizationsNum() > 0)
m_abstractContact->clearOrganizations();
+#ifdef FEATURE_EBOOK
+ // EDS could store multiple ORG properties, but EContact only supports one.
+ // For the sake of simplicity we limit the number of organizations to one
+ // here
+#else
errorCode = contacts_record_get_child_record_count(m_platformContact, _contacts_contact.company, &child_count);
if(errorCode != CONTACTS_ERROR_NONE && errorCode != CONTACTS_ERROR_NO_DATA)
ThrowMsg(UnknownException, "getting company list (err:" << errorCode << ")");
//LoggerD("Platform contact don't have company list");
return;
}
+#endif
ContactOrganizationArrayPtr organizations = m_abstractContact->getOrganizations();
+#ifndef FEATURE_EBOOK
for(unsigned int i=0; i<child_count; i++)
{
contacts_record_h child_record = NULL;
errorCode = contacts_record_get_child_record_at_p(m_platformContact, _contacts_contact.company, i, &child_record);
if(errorCode != CONTACTS_ERROR_NONE && errorCode != CONTACTS_ERROR_NO_DATA)
continue;
+#endif
ContactOrganizationPtr organization(new ContactOrganization());
char *charValue = NULL;
+#ifndef FEATURE_EBOOK
int intValue = 0;
+#endif
+#ifdef FEATURE_EBOOK
+ PlainGStr buffer = EContactFieldCXX<E_CONTACT_ORG>::get(m_platformContact);
+ charValue = buffer;
+#else
contacts_record_get_str_p(child_record, _contacts_company.name, &charValue);
+#endif
if (charValue)
organization->setName(charValue);
else
organization->unsetName();
}
+#ifdef FEATURE_EBOOK
+ buffer = EContactFieldCXX<E_CONTACT_ORG_UNIT>::get(m_platformContact);
+ charValue = buffer;
+#else
contacts_record_get_str_p(child_record, _contacts_company.department, &charValue);
+#endif
if (charValue)
organization->setDepartment(charValue);
else
organization->unsetDepartment();
}
+#ifdef FEATURE_EBOOK
+ buffer = EContactFieldCXX<E_CONTACT_TITLE>::get(m_platformContact);
+ charValue = buffer;
+#else
contacts_record_get_str_p(child_record, _contacts_company.job_title, &charValue);
+#endif
if (charValue)
organization->setTitle(charValue);
else
organization->unsetTitle();
}
+#ifdef FEATURE_EBOOK
+ buffer = EContactFieldCXX<E_CONTACT_ROLE>::get(m_platformContact);
+ charValue = buffer;
+#else
contacts_record_get_str_p(child_record, _contacts_company.role, &charValue);
+#endif
if (charValue)
organization->setRole(charValue);
else
organization->unsetRole();
}
+#ifdef FEATURE_EBOOK
+ charValue = NULL;
+#else
contacts_record_get_str_p(child_record, _contacts_company.logo, &charValue);
+#endif
if (charValue)
organization->setLogoURI(ContactUtility::convertPathToUri(charValue));
else
organization->unsetLogoURI();
}
+#ifdef FEATURE_EBOOK
+ buffer = EContactFieldCXX<E_CONTACT_ASSISTANT>::get(m_platformContact);
+ charValue = buffer;
+#else
contacts_record_get_str_p(child_record, _contacts_company.assistant_name, &charValue);
+#endif
if (charValue)
organization->setAssistant(charValue);
else
organization->unsetAssistant();
}
+#ifdef FEATURE_EBOOK
+ charValue = NULL;
+#else
contacts_record_get_str_p(child_record, _contacts_company.location, &charValue);
+#endif
if (charValue)
organization->setLocation(charValue);
else
organization->unsetLocation();
}
+#ifdef FEATURE_EBOOK
+ charValue = NULL;
+#else
contacts_record_get_str_p(child_record, _contacts_company.description, &charValue);
+#endif
if (charValue)
organization->setDescription(charValue);
else
organization->unsetDescription();
}
+#ifdef FEATURE_EBOOK
+ charValue = NULL;
+#else
contacts_record_get_str_p(child_record, _contacts_company.phonetic_name, &charValue);
+#endif
if (charValue)
organization->setPhoneticName(charValue);
else
organization->unsetPhoneticName();
}
+#ifndef FEATURE_EBOOK
contacts_record_get_int(child_record, _contacts_company.type, &intValue);
if(intValue == CONTACTS_COMPANY_TYPE_OTHER)
organization->setType(ORGANIZATION_TYPE_OTHER);
if(intValue == CONTACTS_COMPANY_TYPE_WORK)
organization->setType(ORGANIZATION_TYPE_WORK);
+#endif
if(organization->getTypeIsSet() == false)
organization->setType(ORGANIZATION_TYPE_WORK);
+
+#ifdef FEATURE_EBOOK
+ charValue = NULL;
+#else
contacts_record_get_str_p(child_record, _contacts_company.label, &charValue);
+#endif
if (charValue)
organization->setLabel(charValue);
else
}
organizations->push_back(organization);
+#ifndef FEATURE_EBOOK
}
+#endif
}
void ContactObjectP2AConverter::exportNoteList()
{
+#ifndef FEATURE_EBOOK
int errorCode = 0;
unsigned int child_count = 0;
+#endif
if(m_abstractContact->getNotesNum() > 0)
m_abstractContact->clearNotes();
+#ifdef FEATURE_EBOOK
+ // Same as ORG - only one NOTE supported.
+#else
errorCode = contacts_record_get_child_record_count(m_platformContact, _contacts_contact.note, &child_count);
if(errorCode != CONTACTS_ERROR_NONE && errorCode != CONTACTS_ERROR_NO_DATA)
ThrowMsg(UnknownException, "getting note list (err:" << errorCode << ")");
//LoggerD("Platform contact don't have note list");
return;
}
+#endif
StringArrayPtr notes = m_abstractContact->getNotes();
+#ifndef FEATURE_EBOOK
for(unsigned int i=0; i<child_count; i++)
{
contacts_record_h child_record = NULL;
errorCode = contacts_record_get_child_record_at_p(m_platformContact, _contacts_contact.note, i, &child_record);
if(errorCode != CONTACTS_ERROR_NONE && errorCode != CONTACTS_ERROR_NO_DATA)
continue;
+#endif
char *charValue = NULL;
+#ifdef FEATURE_EBOOK
+ PlainGStr buffer = EContactFieldCXX<E_CONTACT_NOTE>::get(m_platformContact);
+ charValue = buffer;
+#else
contacts_record_get_str_p(child_record, _contacts_note.note, &charValue);
+#endif
if (charValue)
notes->push_back(charValue);
+#ifndef FEATURE_EBOOK
}
+#endif
}
+#ifdef FEATURE_EBOOK
+static bool IsType(EVCardAttributeParam *param, const char *type)
+{
+ // match shortcut when type is given without TYPE=
+ const char *name = e_vcard_attribute_param_get_name(param);
+ if (!strcasecmp(name, type))
+ return true;
+
+ // TYPE parameter?
+ if (strcasecmp(name, "TYPE"))
+ return false;
+
+ // Check each value of TYPE.
+ GListCXX<char, GList, NoopDestructor<char>, false> values(e_vcard_attribute_param_get_values(param));
+ BOOST_FOREACH (const char *value, values) {
+ if (!strcasecmp(value, type))
+ return true;
+ }
+
+ return false;
+}
+
+
+
+// Implements both exportNumberList and exportEmailList.
+template<class E, class EArray, class T, class V, class AT, class GT>
+void exportList(contacts_record_h &record, Contact *contact,
+ const char *property,
+ const Types<T> *types,
+ T defType,
+ V *(*getValue)(EVCardAttribute *),
+ void (Contact::*clearList)(),
+ EArray (IContact::*getList)() const,
+ const boost::function<void (E &, V *)> set,
+ // Can't be more specific here because
+ // ContactAddress::addType is not consistent with
+ // other addType calls (it uses const, the other's dont).
+ AT addType, // void (E::*addType)(T),
+ GT (E::*getTypes)() const
+ )
+{
+ (contact->*clearList)();
+
+ // workaround for g++/linker issue: method not included in .so unless
+ // we call it explicitly here.
+ NoopDestructor<EVCardAttribute>(NULL);
+ GListCXX<EVCardAttribute, GList, NoopDestructor<EVCardAttribute>, false> attributes(e_vcard_get_attributes(E_VCARD(record.get())));
+ EArray entries = (contact->*getList)();
+
+ BOOST_FOREACH (EVCardAttribute *attribute, attributes)
+ {
+ const char *name = e_vcard_attribute_get_name(attribute);
+ if (!name || strcasecmp(name, property))
+ continue;
+
+ DPL::SharedPtr<E> entry(new E());
+
+ V *value = getValue(attribute);
+ if (value)
+ {
+ set(*entry, value);
+ }
+ else
+ {
+ //LoggerD("Platform contact have a empty phone number");
+ continue;
+ }
+
+ // Same workaround as for GListCXX<EVCardAttribute...
+ NoopDestructor<EVCardAttributeParam>(NULL);
+ GListCXX<EVCardAttributeParam, GList, NoopDestructor<EVCardAttributeParam>, false> params(e_vcard_attribute_get_params(attribute));
+ BOOST_FOREACH (EVCardAttributeParam *param, params) {
+ for (const Types<T> *type = types;
+ type->typeString;
+ type++) {
+ if (IsType(param, type->typeString))
+ ((*entry).*addType)(type->enumVal);
+ }
+ }
+
+ if(((*entry).*getTypes)()->size() == 0)
+ ((*entry).*addType)(defType);
+
+ entries->push_back(entry);
+ }
+}
+
+Types<ContactPhoneNumberType> EDSTelTypes[] = {
+ { "HOME", CONTACT_PHONE_NUMBER_TYPE_HOME },
+ { "WORK", CONTACT_PHONE_NUMBER_TYPE_WORK },
+ { "VOICE", CONTACT_PHONE_NUMBER_TYPE_VOICE },
+ { "FAX", CONTACT_PHONE_NUMBER_TYPE_FAX },
+ { "MSG", CONTACT_PHONE_NUMBER_TYPE_MSG },
+ { "CELL", CONTACT_PHONE_NUMBER_TYPE_CELL },
+ { "PAGER", CONTACT_PHONE_NUMBER_TYPE_PAGER },
+ { "BBS", CONTACT_PHONE_NUMBER_TYPE_BBS },
+ { "MODEM", CONTACT_PHONE_NUMBER_TYPE_MODEM },
+ { "CAR", CONTACT_PHONE_NUMBER_TYPE_CAR },
+ { "ISDN", CONTACT_PHONE_NUMBER_TYPE_ISDN },
+ { "VIDEO", CONTACT_PHONE_NUMBER_TYPE_VIDEO },
+ { "PCS", CONTACT_PHONE_NUMBER_TYPE_PCS },
+ { "X-EVOLUTION-ASSISTANT", CONTACT_PHONE_NUMBER_TYPE_ASSISTANT },
+ { "X-ASSISTANT", CONTACT_PHONE_NUMBER_TYPE_ASSISTANT },
+ { "ASSISTANT", CONTACT_PHONE_NUMBER_TYPE_ASSISTANT },
+ { NULL }
+};
+
+Types<ContactEmailAddressType> EDSEmailTypes[] = {
+ { "HOME", CONTACT_EMAIL_TYPE_HOME },
+ { "WORK", CONTACT_EMAIL_TYPE_WORK },
+ { "MOBILE", CONTACT_EMAIL_TYPE_MOBILE },
+ { NULL }
+};
+
+Types<ContactAddressType> EDSAdrTypes[] = {
+ { "HOME", CONTACT_ADDRESS_TYPE_HOME },
+ { "WORK", CONTACT_ADDRESS_TYPE_WORK },
+ { "DOM", CONTACT_ADDRESS_TYPE_DOM },
+ { "INTL", CONTACT_ADDRESS_TYPE_INTL },
+ { "POSTAL", CONTACT_ADDRESS_TYPE_POSTAL },
+ { "PARCEL", CONTACT_ADDRESS_TYPE_PARCEL },
+ { NULL }
+};
+#endif // FEATURE_EBOOK
+
void ContactObjectP2AConverter::exportNumberList()
{
+#ifdef FEATURE_EBOOK
+ exportList(m_platformContact, &*DPL::StaticPointerCast<Contact>(m_abstractContact),
+ EVC_TEL, EDSTelTypes, CONTACT_PHONE_NUMBER_TYPE_VOICE,
+ e_vcard_attribute_get_value,
+ &Contact::resetNumbersJSObj,
+ &Contact::getPhoneNumbers,
+ boost::function<void (ContactPhoneNumber &, char *)>(boost::bind(&ContactPhoneNumber::setNumber, _1, _2)),
+ &ContactPhoneNumber::addType,
+ &ContactPhoneNumber::getTypes);
+#else
int errorCode = 0;
unsigned int child_count = 0;
phoneNumbers->push_back(phoneNumber);
}
+#endif
}
void ContactObjectP2AConverter::exportEmailList()
{
+#ifdef FEATURE_EBOOK
+ exportList(m_platformContact, &*DPL::StaticPointerCast<Contact>(m_abstractContact),
+ EVC_EMAIL, EDSEmailTypes, CONTACT_EMAIL_TYPE_WORK,
+ e_vcard_attribute_get_value,
+ &Contact::resetEmailsJSObj,
+ &Contact::getEmails,
+ boost::function<void (ContactEmailAddress &, char *)>(boost::bind(&ContactEmailAddress::setEmail, _1, _2)),
+ &ContactEmailAddress::addType,
+ &ContactEmailAddress::getTypes);
+#else
int errorCode = 0;
unsigned int child_count = 0;
emails->push_back(email);
}
+#endif
}
void ContactObjectP2AConverter::exportGrouprelList()
{
+#ifdef FEATURE_EBOOK
+ // Not supported.
+ m_abstractContact->clearGroupIds();
+#else
int errorCode = 0;
unsigned int child_count = 0;
groupIds->push_back(ContactUtility::intToStr(groupId));
}
+#endif
}
void ContactObjectP2AConverter::exportEventList()
{
+#ifdef FEATURE_EBOOK
+ // Generic list of anniversaries not supported by the
+ // mapping. EDS has one anniversary field, we could use that.
+ m_abstractContact->clearAnniversaries();
+
+ boost::shared_ptr<EContactDate> bday = EContactFieldCXX<E_CONTACT_BIRTH_DATE>::get(m_platformContact);
+ if (bday) {
+ tm tmDate = {0, };
+ tmDate.tm_year = bday->year;
+ tmDate.tm_mon = bday->month;
+ tmDate.tm_mday = bday->day;
+ m_abstractContact->setBirthday(tmDate);
+ } else {
+ m_abstractContact->unsetBirthday();
+ }
+#else
int errorCode = 0;
unsigned int child_count = 0;
anniversaries->push_back(anniversary);
}
}
+#endif
+}
+
+#ifdef FEATURE_EBOOK
+const char *getComponent(GList *&values)
+{
+ if (values) {
+ const char *res = static_cast<const char *>(values->data);
+ values = values->next;
+ return res;
+ } else {
+ return NULL;
+ }
+}
+
+static void SetAddress(ContactAddress &address, GList *values)
+{
+ // Treating empty strings as "unset" follows the behavior of
+ // the rest of the code. vCard itself cannot distinguish
+ // well between unset and empty components, because the initial
+ // components must be set if one of the following ones is.
+ const char *charValue = getComponent(values);
+ if (charValue && charValue[0])
+ address.setPostalCode(charValue);
+
+ charValue = getComponent(values);
+ if (charValue && charValue[0])
+ address.setRegion(charValue);
+
+ charValue = getComponent(values);
+ if (charValue && charValue[0])
+ address.setCity(charValue);
+
+ charValue = getComponent(values);
+ if (charValue && charValue[0])
+ address.setStreetAddress(charValue);
+
+ charValue = getComponent(values);
+ if (charValue && charValue[0])
+ address.setAdditionalInformation(charValue);
+
+ charValue = getComponent(values);
+ if (charValue && charValue[0])
+ address.setCountry(charValue);
}
+#endif
void ContactObjectP2AConverter::exportPostalList()
{
+#ifdef FEATURE_EBOOK
+ exportList(m_platformContact, &*DPL::StaticPointerCast<Contact>(m_abstractContact),
+ EVC_ADR, EDSAdrTypes, CONTACT_ADDRESS_TYPE_HOME,
+ e_vcard_attribute_get_values,
+ &Contact::resetAddressesJSObj,
+ &Contact::getAddresses,
+ boost::function<void (ContactAddress &, GList *)>(boost::bind(SetAddress, _1, _2)),
+ &ContactAddress::addType,
+ &ContactAddress::getTypes);
+#else
int errorCode = 0;
unsigned int child_count = 0;
addresses->push_back(address);
}
+#endif
}
void ContactObjectP2AConverter::exportWebAddrList()
{
+#ifdef FEATURE_EBOOK
+ // TODO as time permits.
+#else
int errorCode = 0;
unsigned int child_count = 0;
urls->push_back(url);
}
+#endif
}
void ContactObjectP2AConverter::exportNicknameList()
{
+#ifndef FEATURE_EBOOK
int errorCode = 0;
unsigned int child_count = 0;
+#endif
ContactNamePtr contactName = m_abstractContact->getName();
if(contactName == NULL)
if(contactName->getNicknamesNum() > 0)
contactName->clearNicknames();
+#ifdef FEATURE_EBOOK
+ // Not supported.
+ return;
+#else
errorCode = contacts_record_get_child_record_count(m_platformContact, _contacts_contact.nickname, &child_count);
if(errorCode != CONTACTS_ERROR_NONE && errorCode != CONTACTS_ERROR_NO_DATA)
ThrowMsg(UnknownException, "getting nickname list (err:" << errorCode << ")");
if (charValue)
nicknames->push_back(charValue);
}
+#endif
}
} // Contact
namespace DeviceAPI {
namespace Contact {
+#ifdef FEATURE_EBOOK
+template<class T> struct Types { const char *typeString; T enumVal; };
+extern Types<ContactPhoneNumberType> EDSTelTypes[];
+extern Types<ContactEmailAddressType> EDSEmailTypes[];
+extern Types<ContactAddressType> EDSAdrTypes[];
+#endif
+
class ContactObjectP2AConverter
{
public:
ContactObjectP2AConverter(contacts_record_h platformContact,
+#ifdef FEATURE_EBOOK
+ EBookClientCXX m_ebook,
+#endif
bool forScratch);
ContactObjectP2AConverter(contacts_record_h platformContact,
+#ifdef FEATURE_EBOOK
+ EBookClientCXX m_ebook,
+#endif
bool forScratch,
ContactPtr &abstractContact);
virtual ~ContactObjectP2AConverter();
void exportNicknameList();
contacts_record_h m_platformContact;
+#ifdef FEATURE_EBOOK
+ EBookClientCXX m_ebook;
+#endif
ContactPtr m_abstractContact;
bool m_forScratch;
bool m_convertFinished;
#include "ContactUtility.h"
#include <Logger.h>
+#ifdef FEATURE_EBOOK
+# include <boost/scoped_array.hpp>
+#endif
+
#define _CONTACTS_SVC_QUERY_FUNC_PREFIX(view_uri, query, filter) \
do { \
if((errorCode = contacts_query_create(view_uri, &query)) != CONTACTS_ERROR_NONE) \
using namespace DeviceAPI::Tizen;
using namespace std;
+// Picks first two parameters when using contacts service, otherwise the last two.
+// Use NULL, E_CONTACT_FIELD_LAST for EDS vCardField/contactField when searching
+// is not supported in EDS for that attribute.
+#ifdef FEATURE_EBOOK
+# define IF_SVC_ELSE(_viewUri, _propertyContactId, _propertyId, _vCardField, _contactField) _vCardField, _contactField
+#else
+# define IF_SVC_ELSE(_viewUri, _propertyContactId, _propertyId, _vCardField, _contactField) _viewUri, _propertyContactId, _propertyId
+#endif
+
+
ContactSearchEngine::AttributePropertiesMap ContactSearchEngine::attributePropertiesMap = {
- {"id", { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.id, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_String } },
- {"personId", { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.person_id, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_String } },
- {"addressBookId", { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.address_book_id, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_String } },
- {"lastUpdated", { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.changed_time, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Time } },
- {"isFavorite", { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.is_favorite, ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
- {"name.prefix", { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.prefix, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"name.suffix", { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.suffix, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"name.firstName", { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.first, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"name.middleName", { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.addition, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"name.lastName", { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.last, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"name.nicknames", { _contacts_nickname._uri, _contacts_nickname.contact_id, _contacts_nickname.name, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"name.phoneticFirstName", { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.phonetic_first, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"name.phoneticMiddleName", { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.phonetic_middle, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"name.phoneticLastName", { _contacts_name._uri, _contacts_name.contact_id, _contacts_name.phonetic_last, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"name.displayName", { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.display_name, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"addresses.country", { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.country, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"addresses.region", { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.region, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"addresses.city", { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.locality, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"addresses.streetAddress", { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.street, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"addresses.additionalInformation", { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.extended, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"addresses.postalCode", { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.postal_code, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"addresses.isDefault", { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.is_default, ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
- {"addresses.types", { _contacts_address._uri, _contacts_address.contact_id, _contacts_address.type, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
- {"photoURI", { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.image_thumbnail_path, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"phoneNumbers.number", { _contacts_number._uri, _contacts_number.contact_id, _contacts_number.number, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"phoneNumbers.isDefault", { _contacts_number._uri, _contacts_number.contact_id, _contacts_number.is_default, ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
- {"phoneNumbers.types", { _contacts_number._uri, _contacts_number.contact_id, _contacts_number.type, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
- {"emails.email", { _contacts_email._uri, _contacts_email.contact_id, _contacts_email.email, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"emails.isDefault", { _contacts_email._uri, _contacts_email.contact_id, _contacts_email.is_default, ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
- {"emails.types", { _contacts_email._uri, _contacts_email.contact_id, _contacts_email.type, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
- {"birthday", { _contacts_event._uri, _contacts_event.contact_id, _contacts_event.date, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
- {"anniversaries.date", { _contacts_event._uri, _contacts_event.contact_id, _contacts_event.date, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
- {"anniversaries.label", { _contacts_event._uri, _contacts_event.contact_id, _contacts_event.label, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"organizations.name", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.name, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"organizations.department",{ _contacts_company._uri, _contacts_company.contact_id, _contacts_company.department, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"organizations.title", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.job_title, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"organizations.role", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.role, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"organizations.logoURI", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.logo, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"organizations.assistant", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.assistant_name, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"organizations.location", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.location, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"organizations.description", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.description, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"organizations.phoneticName", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.phonetic_name, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"organizations.type", { _contacts_company._uri, _contacts_company.contact_id, _contacts_company.type, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_Long } },
- {"notes", { _contacts_note._uri, _contacts_note.contact_id, _contacts_note.note, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"urls.url", { _contacts_url._uri, _contacts_url.contact_id, _contacts_url.url, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"urls.type", { _contacts_url._uri, _contacts_url.contact_id, _contacts_url.type, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
- {"ringtoneURI", { _contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.ringtone_path, ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
- {"groupIds", { _contacts_group_relation._uri, _contacts_group_relation.contact_id, _contacts_group_relation.group_id, ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } }
+
+ {"id", { IF_SVC_ELSE(_contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.id, NULL, E_CONTACT_UID), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_String } },
+ {"personId", { IF_SVC_ELSE(_contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.person_id, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_String } },
+ {"addressBookId", { IF_SVC_ELSE(_contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.address_book_id, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_String } },
+ {"lastUpdated", { IF_SVC_ELSE(_contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.changed_time, NULL, E_CONTACT_REV), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Time } },
+ {"isFavorite", { IF_SVC_ELSE(_contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.is_favorite, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
+ {"name.prefix", { IF_SVC_ELSE(_contacts_name._uri, _contacts_name.contact_id, _contacts_name.prefix, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"name.suffix", { IF_SVC_ELSE(_contacts_name._uri, _contacts_name.contact_id, _contacts_name.suffix, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"name.firstName", { IF_SVC_ELSE(_contacts_name._uri, _contacts_name.contact_id, _contacts_name.first, NULL, E_CONTACT_GIVEN_NAME), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"name.middleName", { IF_SVC_ELSE(_contacts_name._uri, _contacts_name.contact_id, _contacts_name.addition, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"name.lastName", { IF_SVC_ELSE(_contacts_name._uri, _contacts_name.contact_id, _contacts_name.last, NULL, E_CONTACT_FAMILY_NAME), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"name.nicknames", { IF_SVC_ELSE(_contacts_nickname._uri, _contacts_nickname.contact_id, _contacts_nickname.name, NULL, E_CONTACT_NICKNAME), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"name.phoneticFirstName", { IF_SVC_ELSE(_contacts_name._uri, _contacts_name.contact_id, _contacts_name.phonetic_first, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"name.phoneticMiddleName", { IF_SVC_ELSE(_contacts_name._uri, _contacts_name.contact_id, _contacts_name.phonetic_middle, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"name.phoneticLastName", { IF_SVC_ELSE(_contacts_name._uri, _contacts_name.contact_id, _contacts_name.phonetic_last, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"name.displayName", { IF_SVC_ELSE(_contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.display_name, NULL, E_CONTACT_NAME_OR_ORG), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"addresses.country", { IF_SVC_ELSE(_contacts_address._uri, _contacts_address.contact_id, _contacts_address.country, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"addresses.region", { IF_SVC_ELSE(_contacts_address._uri, _contacts_address.contact_id, _contacts_address.region, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"addresses.city", { IF_SVC_ELSE(_contacts_address._uri, _contacts_address.contact_id, _contacts_address.locality, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"addresses.streetAddress", { IF_SVC_ELSE(_contacts_address._uri, _contacts_address.contact_id, _contacts_address.street, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"addresses.additionalInformation", { IF_SVC_ELSE(_contacts_address._uri, _contacts_address.contact_id, _contacts_address.extended, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"addresses.postalCode", { IF_SVC_ELSE(_contacts_address._uri, _contacts_address.contact_id, _contacts_address.postal_code, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"addresses.isDefault", { IF_SVC_ELSE(_contacts_address._uri, _contacts_address.contact_id, _contacts_address.is_default, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
+ {"addresses.types", { IF_SVC_ELSE(_contacts_address._uri, _contacts_address.contact_id, _contacts_address.type, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
+ {"photoURI", { IF_SVC_ELSE(_contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.image_thumbnail_path, EVC_PHOTO, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"phoneNumbers.number", { IF_SVC_ELSE(_contacts_number._uri, _contacts_number.contact_id, _contacts_number.number, EVC_TEL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"phoneNumbers.isDefault", { IF_SVC_ELSE(_contacts_number._uri, _contacts_number.contact_id, _contacts_number.is_default, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
+ {"phoneNumbers.types", { IF_SVC_ELSE(_contacts_number._uri, _contacts_number.contact_id, _contacts_number.type, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
+ {"emails.email", { IF_SVC_ELSE(_contacts_email._uri, _contacts_email.contact_id, _contacts_email.email, EVC_EMAIL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"emails.isDefault", { IF_SVC_ELSE(_contacts_email._uri, _contacts_email.contact_id, _contacts_email.is_default, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Boolean, PrimitiveType_Boolean } },
+ {"emails.types", { IF_SVC_ELSE(_contacts_email._uri, _contacts_email.contact_id, _contacts_email.type, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
+ {"birthday", { IF_SVC_ELSE(_contacts_event._uri, _contacts_event.contact_id, _contacts_event.date, NULL, E_CONTACT_BIRTH_DATE), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
+ {"anniversaries.date", { IF_SVC_ELSE(_contacts_event._uri, _contacts_event.contact_id, _contacts_event.date, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
+ {"anniversaries.label", { IF_SVC_ELSE(_contacts_event._uri, _contacts_event.contact_id, _contacts_event.label, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"organizations.name", { IF_SVC_ELSE(_contacts_company._uri, _contacts_company.contact_id, _contacts_company.name, NULL, E_CONTACT_ORG), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"organizations.department",{ IF_SVC_ELSE(_contacts_company._uri, _contacts_company.contact_id, _contacts_company.department, NULL, E_CONTACT_ORG_UNIT), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"organizations.title", { IF_SVC_ELSE(_contacts_company._uri, _contacts_company.contact_id, _contacts_company.job_title, NULL, E_CONTACT_TITLE), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"organizations.role", { IF_SVC_ELSE(_contacts_company._uri, _contacts_company.contact_id, _contacts_company.role, NULL, E_CONTACT_ROLE), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"organizations.logoURI", { IF_SVC_ELSE(_contacts_company._uri, _contacts_company.contact_id, _contacts_company.logo, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"organizations.assistant", { IF_SVC_ELSE(_contacts_company._uri, _contacts_company.contact_id, _contacts_company.assistant_name, NULL, E_CONTACT_ASSISTANT), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"organizations.location", { IF_SVC_ELSE(_contacts_company._uri, _contacts_company.contact_id, _contacts_company.location, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"organizations.description", { IF_SVC_ELSE(_contacts_company._uri, _contacts_company.contact_id, _contacts_company.description, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"organizations.phoneticName", { IF_SVC_ELSE(_contacts_company._uri, _contacts_company.contact_id, _contacts_company.phonetic_name, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"organizations.type", { IF_SVC_ELSE(_contacts_company._uri, _contacts_company.contact_id, _contacts_company.type, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_Long } },
+ {"notes", { IF_SVC_ELSE(_contacts_note._uri, _contacts_note.contact_id, _contacts_note.note, NULL, E_CONTACT_NOTE), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"urls.url", { IF_SVC_ELSE(_contacts_url._uri, _contacts_url.contact_id, _contacts_url.url, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"urls.type", { IF_SVC_ELSE(_contacts_url._uri, _contacts_url.contact_id, _contacts_url.type, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } },
+ {"ringtoneURI", { IF_SVC_ELSE(_contacts_simple_contact._uri, _contacts_simple_contact.id, _contacts_simple_contact.ringtone_path, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_String, PrimitiveType_String } },
+ {"groupIds", { IF_SVC_ELSE(_contacts_group_relation._uri, _contacts_group_relation.contact_id, _contacts_group_relation.group_id, NULL, E_CONTACT_FIELD_LAST), ContactSearchEngine::ContactSvcPrimitiveType_Int, PrimitiveType_Long } }
};
-ContactSearchEngine::ContactSearchEngine() :
+ContactSearchEngine::ContactSearchEngine(
+#ifdef FEATURE_EBOOK
+ EBookClientCXX &ebook
+#endif
+
+ ) :
+#ifdef FEATURE_EBOOK
+ m_ebook(ebook),
+#endif
m_addressBookId(0),
m_isAddressBookIdSet(false),
m_isFilterSet(false),
return;
IFilterVisitorPtr filterQuery = DPL::StaticPointerCast<IFilterVisitor>(SharedFromThis());
- filter->travel(filterQuery);
+#ifdef FEATURE_EBOOK
+ // Set up root level of queries.
+ m_queries.clear();
+ m_queries.resize(1);
+ filter->travel(filterQuery);
+ m_isFilterSet = true;
+#else
+ filter->travel(filterQuery);
if(m_filteredContactIds != NULL)
m_isFilterSet = true;
- }
+#endif
+}
void ContactSearchEngine::setSortMode(SortModePtr attr)
{
ContactArrayPtr ContactSearchEngine::getContactSearchResult()
{
ContactArrayPtr result(NULL);
- unsigned int length = 0;
LoggerD("entered");
+#ifdef FEATURE_EBOOK
+ if (!m_isSortModeSet && !m_isFilterSet) {
+ // Fast path: just read all contacts, unsorted.
+ result = getAllContacts();
+ } else {
+ result = ContactArrayPtr(new ContactArray);
+
+ // Sort and/or filtering using the EDS cursor API.
+ EBookQueryCXX query;
+ if (m_queries.empty() ||
+ m_queries[0].empty()) {
+ query.take(e_book_query_any_field_contains(""));
+ } else {
+ query = m_queries[0][0];
+ }
+ PlainGStr sexp(e_book_query_to_string(query));
+ static EContactField sortFields[2] = {
+ // Hard-coded sorting. Currently we don't have
+ // support for choosing a specific order.
+ E_CONTACT_FAMILY_NAME,
+ E_CONTACT_GIVEN_NAME
+ };
+ EBookCursorSortType order = (!m_isSortModeSet || m_sortOrder == ASCENDING_SORT_ORDER) ?
+ E_BOOK_CURSOR_SORT_ASCENDING :
+ E_BOOK_CURSOR_SORT_DESCENDING;
+ EBookCursorSortType sortOrder[2] = {
+ order, order
+ };
+
+ EBookClientCursorCXX cursor;
+ EBookClientCursor *tmpCursor;
+ GErrorCXX gerror;
+ if (!e_book_client_get_cursor_sync(m_ebook,
+ sexp,
+ sortFields,
+ sortOrder,
+ 2, // entries in sortFields and sortOrder
+ &tmpCursor,
+ NULL,
+ gerror)) {
+ ThrowMsg(PlatformException, "e_book_client_get_cursors_sync: " << gerror.msg());
+ }
+ cursor.take(tmpCursor);
+ static const int stepSize = 1000;
+ while (true) {
+ GSList *tmpContacts;
+ gint num = e_book_client_cursor_step_sync(cursor,
+ (EBookCursorStepFlags)(E_BOOK_CURSOR_STEP_MOVE|E_BOOK_CURSOR_STEP_FETCH),
+ E_BOOK_CURSOR_ORIGIN_CURRENT,
+ stepSize,
+ &tmpContacts,
+ NULL,
+ gerror);
+ if (num == -1) {
+ ThrowMsg(PlatformException, "e_book_client_cursor_step_sync: " << gerror.msg());
+ }
+ contacts_list_h contacts(tmpContacts);
+ BOOST_FOREACH (EContact *econtact, contacts) {
+ contacts_record_h record(econtact, ADD_REF);
+ ContactPtr contact(NULL);
+ Try
+ {
+ ContactObjectP2AConverterPtr contactObjConverter(
+ new ContactObjectP2AConverter(record,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false));
+ contact = contactObjConverter->getAbstractContact();
+ }
+ Catch(Exception)
+ {
+ LoggerW("fail to convert contact");
+ continue;
+ }
+
+ result->push_back(contact);
+ }
+ if (num < stepSize) {
+ break;
+ }
+ }
+ }
+#else
if(m_isFilterSet)
{
+ unsigned int length = 0;
if(m_isSortModeSet)
{
ContactIdArrayPtr ids = ContactIdArrayPtr(new ContactIdArray());
result = getAllContacts();
}
}
+#endif
LoggerD("End");
return result;
void ContactSearchEngine::visitPreComposite(FilterType& type, int depth)
{
+#ifdef FEATURE_EBOOK
+ m_queries.resize(m_queries.size() + 1);
+#else
ContactIdSetArrayPtr idSets = ContactIdSetArrayPtr(new ContactIdSetArray());
m_contactIdSetArrayStack.push(idSets);
+#endif
}
void ContactSearchEngine::visitInComposite(FilterType& type, int depth)
void ContactSearchEngine::visitPostComposite(FilterType& type, int depth)
{
+#ifdef FEATURE_EBOOK
+ CurrentQueries sub = m_queries.back();
+ m_queries.resize(m_queries.size() - 1);
+ CurrentQueries ¤t = m_queries.back();
+ EBookQueryCXX composite;
+ // Temporary array for EDS.
+ boost::scoped_array<EBookQuery *> buffer(new EBookQuery *[sub.size()]);
+ for (size_t i = 0; i < sub.size(); i++) {
+ buffer[i] = sub[i].get();
+ }
+ composite.take((type == UNION_FILTER ? e_book_query_or : e_book_query_and)
+ (sub.size(), buffer.get(), false));
+ current.push_back(composite);
+#else
ContactIdSetArrayPtr idSets = m_contactIdSetArrayStack.top();
m_contactIdSetArrayStack.pop();
parentIdSets->push_back(idSet);
}
}
+#endif
}
void ContactSearchEngine::visitAttribute(string& attrName, MatchFlag& matchFlag, AnyPtr& matchValue, int depth)
if(matchValue == NULL || matchValue->isNullOrUndefined())
matchFlag = MATCH_EXISTS;
+#ifdef FEATURE_EBOOK
+ AttributePropertiesMap::iterator iter =
+ attributePropertiesMap.find(attrName);
+ if (iter == attributePropertiesMap.end())
+ ThrowMsg(NotFoundException, "There is no attribute name for filter : " << attrName);
+ AttributeProperties &properties = iter->second;
+ if (!properties.vCardField && properties.contactField == E_CONTACT_FIELD_LAST)
+ ThrowMsg(UnsupportedException, "Filtering by this field not supported: " << attrName);
+ string value;
+ if (properties.jsType == PrimitiveType_String) {
+ value = matchValue->getString();
+ } else if (matchFlag != MATCH_EXISTS) {
+ // Only string value matches are supported. Other
+ // fields can only be checked for existence.
+ ThrowMsg(UnsupportedException, "Filtering field " << attrName << " by value is not supported.");
+ }
+ EBookQueryCXX query;
+ if (properties.vCardField) {
+ switch (matchFlag) {
+ case MATCH_EXISTS:
+ query.take(e_book_query_vcard_field_exists(properties.vCardField));
+ break;
+ case MATCH_EXACTLY:
+ // Matching exactly is not supported accurately. Fall back to
+ // less exact full string comparison.
+ case MATCH_FULLSTRING:
+ query.take(e_book_query_vcard_field_test(properties.vCardField, E_BOOK_QUERY_IS, value.c_str()));
+ break;
+ case MATCH_STARTSWITH:
+ query.take(e_book_query_vcard_field_test(properties.vCardField, E_BOOK_QUERY_BEGINS_WITH, value.c_str()));
+ break;
+ case MATCH_ENDSWITH:
+ query.take(e_book_query_vcard_field_test(properties.vCardField, E_BOOK_QUERY_ENDS_WITH, value.c_str()));
+ case MATCH_CONTAINS:
+ query.take(e_book_query_vcard_field_test(properties.vCardField, E_BOOK_QUERY_CONTAINS, value.c_str()));
+ case MATCH_NONE:
+ break;
+ }
+ } else {
+ switch (matchFlag) {
+ case MATCH_EXISTS:
+ query.take(e_book_query_field_exists(properties.contactField));
+ break;
+ case MATCH_EXACTLY:
+ // Matching exactly is not supported accurately. Fall back to
+ // less exact full string comparison.
+ case MATCH_FULLSTRING:
+ query.take(e_book_query_field_test(properties.contactField, E_BOOK_QUERY_IS, value.c_str()));
+ break;
+ case MATCH_STARTSWITH:
+ query.take(e_book_query_field_test(properties.contactField, E_BOOK_QUERY_BEGINS_WITH, value.c_str()));
+ break;
+ case MATCH_ENDSWITH:
+ query.take(e_book_query_field_test(properties.contactField, E_BOOK_QUERY_ENDS_WITH, value.c_str()));
+ case MATCH_CONTAINS:
+ query.take(e_book_query_field_test(properties.contactField, E_BOOK_QUERY_CONTAINS, value.c_str()));
+ case MATCH_NONE:
+ break;
+ }
+ }
+ CurrentQueries ¤t = m_queries.back();
+ current.push_back(query);
+#else
ContactIdSetPtr idSet = ContactIdSetPtr(new ContactIdSet());
if(attrName == "id")
parentIdSets->push_back(idSet);
}
}
+#endif
}
void ContactSearchEngine::visitAttributeRange(string& attrName, AnyPtr& initialValue, AnyPtr& endValue, int depth)
{
+#ifdef FEATURE_EBOOK
+ ThrowMsg(UnsupportedException, "Filtering by value range is not supported.");
+#else
ContactIdSetPtr idSet = ContactIdSetPtr(new ContactIdSet());
bool initialValueIsSet = true;
ContactIdSetArrayPtr parentIdSets = m_contactIdSetArrayStack.top();
parentIdSets->push_back(idSet);
}
+#endif
}
+#ifndef FEATURE_EBOOK
ContactArrayPtr ContactSearchEngine::getAllContactsSorted(AttributeProperties& attributeProperties, bool is_ascending)
{
ContactArrayPtr contacts = ContactArrayPtr(new ContactArray());
return contacts;
}
+#endif
ContactArrayPtr ContactSearchEngine::getAllContacts()
{
- int errorCode = 0;
-
ContactArrayPtr contacts(new ContactArray());
- contacts_list_h list = NULL;
+ contacts_list_h list(NULL);
+
+#ifdef FEATURE_EBOOK
+ EBookQueryCXX allItemsQuery(e_book_query_any_field_contains(""), TRANSFER_REF);
+ PlainGStr sexp(e_book_query_to_string (allItemsQuery.get()));
+ GSList *elist;
+ GErrorCXX gerror;
+ if (!e_book_client_get_contacts_sync(m_ebook, sexp, &elist, NULL, gerror))
+ ThrowMsg(PlatformException, "e_book_client_get_contacts_sync: " << gerror.msg());
+ list.reset(elist);
+#else
+ int errorCode = 0;
if(!m_isAddressBookIdSet)
{
if(errorCode != CONTACTS_ERROR_NONE)
ThrowMsg(PlatformException, "Fail to get contacts_list_get_count : " << errorCode << " (" << __FUNCTION__ << ")");
LoggerD("END: pure contact-svc");
+#endif
+#ifdef FEATURE_EBOOK
+ BOOST_FOREACH (EContact *econtact, list)
+#else
contacts_list_first(list);
for(unsigned int i=0; i<record_count; i++)
+#endif
{
+#ifdef FEATURE_EBOOK
+ contacts_record_h record(econtact, ADD_REF);
+#else
contacts_record_h record;
errorCode = contacts_list_get_current_record_p(list, &record);
if(errorCode != CONTACTS_ERROR_NONE || record == NULL)
LoggerW("contacts_list_get_current_record_p error : " << errorCode << " (" << __FUNCTION__ << ")");
continue;
}
+#endif
ContactPtr contact(NULL);
Try
{
ContactObjectP2AConverterPtr contactObjConverter(
- new ContactObjectP2AConverter(record, false));
+ new ContactObjectP2AConverter(record,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false));
contact = contactObjConverter->getAbstractContact();
}
contacts->push_back(contact);
+#ifndef FEATURE_EBOOK
contacts_list_next(list);
+#endif
}
- if(list != NULL)
+ if(list)
contacts_list_destroy(list, true);
LoggerD("END: convertToPlugin Objects");
return contacts;
}
+#ifndef FEATURE_EBOOK
ContactArrayPtr ContactSearchEngine::getContacts(ContactIdArrayPtr& ids)
{
ContactArrayPtr contacts(new ContactArray());
}
ContactObjectP2AConverterPtr contactObjConverter(
- new ContactObjectP2AConverter(record, false));
+ new ContactObjectP2AConverter(record,
+#ifdef FEATURE_EBOOK
+ m_ebook,
+#endif
+ false));
ContactPtr contact = contactObjConverter->getAbstractContact();
return contact;
}
}
+#endif // FEATURE_EBOOK
+
} // Contact
} // DeviceAPI
public DPL::EnableSharedFromThis<ContactSearchEngine>
{
public:
- ContactSearchEngine();
+ ContactSearchEngine(
+#ifdef FEATURE_EBOOK
+ EBookClientCXX &ebook
+#endif
+ );
virtual ~ContactSearchEngine();
// setting search options.
struct AttributeProperties
{
+#ifdef FEATURE_EBOOK
+ const gchar *vCardField;
+ const EContactField contactField;
+#else
const char* viewUri;
const unsigned int propertyContactId;
const unsigned int propertyId;
+#endif
const ContactSvcPrimitiveType type;
const DeviceAPI::Tizen::PrimitiveType jsType;
};
typedef std::map<std::string, AttributeProperties> AttributePropertiesMap;
+#ifdef FEATURE_EBOOK
+ // When using EDS, the JS search query is translated into an EBookQuery
+ // and one search operation is executed which returns the final result
+ // data immediately.
+#else
+ // When using contacts service, each JS term triggers one DB
+ // search operation. The ContactSearchEngine then combines the
+ // results and as a last step, retrieves the data for the final
+ // result set.
typedef std::vector<int> ContactIdArray;
typedef DPL::SharedPtr<ContactIdArray> ContactIdArrayPtr;
typedef std::vector<ContactIdSetPtr> ContactIdSetArray;
typedef DPL::SharedPtr<ContactIdSetArray> ContactIdSetArrayPtr;
+#endif
private:
static AttributePropertiesMap attributePropertiesMap;
+#ifdef FEATURE_EBOOK
+ EBookClientCXX m_ebook;
+#endif
int m_addressBookId;
bool m_isAddressBookIdSet;
bool m_isFilterSet;
bool m_isSortModeSet;
+#ifdef FEATURE_EBOOK
+ typedef std::vector<EBookQueryCXX> CurrentQueries;
+ typedef std::vector<CurrentQueries> SubQueries;
+
+ // Grows when entering a composite query, shrinks
+ // when leaving it. At each level it contains the queries
+ // which need to be combined to form the composite query.
+ // The final query to run is m_queries[0][0].
+ SubQueries m_queries;
+#else
std::stack<ContactIdSetArrayPtr> m_contactIdSetArrayStack;
// NULL means ALL
ContactIdSetPtr m_filteredContactIds;
ContactIdArrayPtr m_sortedContactIds;
+#endif
DeviceAPI::Tizen::SortOrder m_sortOrder;
std::string m_attributeNameForSort;
ContactArrayPtr getAllContactsSorted(AttributeProperties& attributeProperties,
bool is_ascending);
ContactArrayPtr getAllContacts();
+
+#ifndef FEATURE_EBOOK
ContactArrayPtr getContacts(ContactIdArrayPtr& ids);
ContactArrayPtr getContacts(ContactIdSetPtr& ids);
ContactPtr getContact(int id);
void getIntersection(ContactIdSetArrayPtr& idSets, ContactIdSetPtr& result);
void getUnion(ContactIdSetArrayPtr& idSets, ContactIdSetPtr& result);
+#endif
};
typedef DPL::SharedPtr<ContactSearchEngine> ContactSearchEnginePtr;
* @brief
*/
+#ifdef FEATURE_EBOOK
+// Changes have to be watched by each AddressBook individually.
+#else
+
#include "ContactsSvcChangeListenerManager.h"
#include <contacts.h>
#include <dpl/singleton_impl.h>
} // Application
} // DeviceAPI
+
+#endif // FEATURE_EBOOK
#ifndef TIZENAPIS_PLATFORM_CONTACT_CONTACT_LISTENER_MANAGER_H_
#define TIZENAPIS_PLATFORM_CONTACT_CONTACT_LISTENER_MANAGER_H_
+#ifdef FEATURE_EBOOK
+// Changes have to be watched by each AddressBook individually. This
+// code simply does nothing.
+
+class IContactsSvcContactsChangeListener {};
+class IContactsSvcPersonsChangeListener {};
+
+#else
+
#include <string>
#include <map>
#include <set>
} // Contact
} // DeviceAPI
+#endif // FEATURE_EBOOK
+
#endif // TIZENAPIS_PLATFORM_CONTACT_CONTACT_LISTENER_MANAGER_H_
using namespace WrtDeviceApis::Commons;
using namespace std;
+#ifndef FEATURE_EBOOK
static const char *EMPTY_STRING = "";
+#endif
ContactsSvcObjectConverter::ContactsSvcObjectConverter()
{
void ContactsSvcObjectConverter::convertToAbstract(contacts_record_h record, PersonPtr& person)
{
+#ifdef FEATURE_EBOOK
+ ThrowMsg(UnsupportedException, "person concept not supported");
+#else
if(record == NULL)
{
ThrowMsg(InvalidArgumentException, "Platform person object did not set");
ThrowMsg(PlatformException, "error on contacts_record_get_int (display_contact_id) (errorCode:" << errorCode << ")");
person->setDisplayContactId(intValue);
+#endif
}
void ContactsSvcObjectConverter::convertToPlatform(PersonPtr& person, contacts_record_h record)
{
+#ifdef FEATURE_EBOOK
+ ThrowMsg(UnsupportedException, "person concept not supported");
+#else
if(record == NULL)
{
ThrowMsg(InvalidArgumentException, "Platform person object did not set");
{
ThrowMsg(PlatformException, "importing displayContactId E (err:" << errorCode << ", value:" << intValue << ")");
}
+#endif
}
void ContactsSvcObjectConverter::convertToAbstract(contacts_record_h record, ContactPtr& contact)
void ContactsSvcObjectConverter::convertToAbstract(contacts_record_h record, ContactGroupPtr& group)
{
+#ifdef FEATURE_EBOOK
+ ThrowMsg(UnsupportedException, "person concept not supported");
+#else
if(record == NULL)
{
ThrowMsg(InvalidArgumentException, "Platform group object did not set");
ThrowMsg(PlatformException, "importing ringtoneURI E (err:" << errorCode);
}
}
+#endif
}
} // Contact
// Caution : This class MUST be used on an identical thread.
ContactsSvcWrapper::ContactsSvcWrapper() :
- m_opened(false),
- m_defaultAddressBook(NULL),
+ m_opened(false)
+#ifndef FEATURE_EBOOK
+ , m_defaultAddressBook(NULL),
m_unifiedAddressBook(NULL),
m_addressBooks(new AddressBookArray())
+#endif
{
init();
}
ContactsSvcWrapper::~ContactsSvcWrapper()
{
+#ifndef FEATURE_EBOOK
//when it is last instance then close connection to database
if(m_opened)
{
LoggerE("Error occurred during closing contacts database. (ret:" << ret << ")");
}
}
+#endif
}
AddressBookPtr ContactsSvcWrapper::getAddressBook(const std::string &id)
ThrowMsg(PlatformException, "Contact DB is not open.");
}
+#ifdef FEATURE_EBOOK
+ AddressBooks_t::const_iterator it = m_addressBooks.find(id == "0" ? "system-address-book" : id);
+ if (it == m_addressBooks.end())
+ ThrowMsg(NotFoundException, "Address book not found");
+ return it->second;
+#else
if(m_idMap.find(id) == m_idMap.end())
ThrowMsg(NotFoundException, "No AddressBook1 ");
ThrowMsg(NotFoundException, "No AddressBook2 ");
return m_addressBooks->at(index);
+#endif
}
AddressBookPtr ContactsSvcWrapper::getDefaultAddressBook()
ThrowMsg(PlatformException, "Contact DB is not open.");
}
+#ifdef FEATURE_EBOOK
+ ESourceCXX esource(e_source_registry_ref_default_address_book(m_sourceRegistry), TRANSFER_REF);
+ AddressBooks_t::const_iterator it = m_addressBooks.find(e_source_get_uid(esource));
+ if (it == m_addressBooks.end())
+ ThrowMsg(NotFoundException, "Default address book not found");
+ return it->second;
+#else
if(m_addressBooks->size() == 0)
ThrowMsg(PlatformException, "Invalid request");
return m_defaultAddressBook;
+#endif
+
}
AddressBookPtr ContactsSvcWrapper::getUnifiedAddressBook()
ThrowMsg(PlatformException, "Contact DB is not open.");
}
+#ifdef FEATURE_EBOOK
+ ThrowMsg(UnsupportedException, "Unified address book not supported");
+ return AddressBookPtr();
+#else
if(m_addressBooks->size() == 0)
ThrowMsg(PlatformException, "Invalid request");
return m_unifiedAddressBook;
+#endif
}
AddressBookArrayPtr ContactsSvcWrapper::getAddressBooks()
AddressBookArrayPtr newArray(new AddressBookArray());
+#ifdef FEATURE_EBOOK
+ BOOST_FOREACH (const AddressBooks_t::value_type &entry, m_addressBooks)
+ newArray->push_back(entry.second);
+#else
for(AddressBookArray::iterator i = m_addressBooks->begin(); i != m_addressBooks->end(); i++)
newArray->push_back(*i);
+#endif
return newArray;
}
LoggerD("entered");
+#ifdef FEATURE_EBOOK
+ if (!access("/tmp/debug-contacts", R_OK)) {
+ FILE *f = fopen("/tmp/contacts-wrt.pid", "w");
+ fprintf(f, "%ld", (long)getpid());
+ fclose(f);
+ sleep(10);
+ }
+
+ GErrorCXX gerror;
+ m_sourceRegistry.take(e_source_registry_new_sync(NULL, gerror));
+ if (!m_sourceRegistry) {
+ LoggerE("Error occurred during creation of ESourceRegistry: " << gerror.msg());
+ return;
+ }
+ m_sourceRegistry.connectSignal<void(ESource *)>("source-added", boost::bind(&ContactsSvcWrapper::addSource, this, _1));
+ m_sourceRegistry.connectSignal<void(ESource *)>("source-enabled", boost::bind(&ContactsSvcWrapper::addSource, this, _1));
+ m_sourceRegistry.connectSignal<void(ESource *)>("source-removed", boost::bind(&ContactsSvcWrapper::removeSource, this, _1));
+ m_sourceRegistry.connectSignal<void(ESource *)>("source-disabled", boost::bind(&ContactsSvcWrapper::removeSource, this, _1));
+#else
int ret = contacts_connect2();
if (ret != CONTACTS_ERROR_NONE)
{
return;
}
+#endif
//contacts-service has properly connected.
LoggerD("Contact db has properly opened.");
{
LoggerD("Loading AddressBook");
+#ifdef FEATURE_EBOOK
+ ESourceList esources(e_source_registry_list_sources(m_sourceRegistry, E_SOURCE_EXTENSION_ADDRESS_BOOK));
+ BOOST_FOREACH (ESource *esource, esources)
+ addSource(esource);
+#else
int errorCode = 0;
contacts_list_h addressbooks_list = NULL;
contacts_list_destroy(addressbooks_list, true);
return;
}
+#endif
+}
+
+#ifdef FEATURE_EBOOK
+
+void ContactsSvcWrapper::addSource(ESource *esource)
+{
+ // Don't add when not enabled or not an address book.
+ if (!e_source_get_enabled(esource) ||
+ !e_source_has_extension(esource, E_SOURCE_EXTENSION_ADDRESS_BOOK))
+ return;
+
+ // Don't add again when already known.
+ const char *uid = e_source_get_uid(esource);
+ AddressBooks_t::const_iterator it = m_addressBooks.find(uid);
+ if (it != m_addressBooks.end())
+ return;
+
+ // Open address book now. AddressBook itself has no notion of
+ // "opening" itself.
+ GErrorCXX gerror;
+ EBookClientCXX ebook(E_BOOK_CLIENT(e_book_client_connect_direct_sync(m_sourceRegistry, esource, NULL, gerror)), TRANSFER_REF);
+ if (!ebook) {
+ LoggerE("Error occurred when opening address book " << uid << ": " << gerror.msg());
+ return;
+ }
+
+ AddressBookPtr addressBook(new AddressBook(ebook));
+ const char *name = e_source_get_display_name(esource);
+ addressBook->setName(name);
+ // Strictly speaking, this is IVI specific: in IVI, only the system address book
+ // is writable. Everything else are currently cached address books from phones
+ // which must not be modified even though EDS would allow it.
+ //
+ // TODO: add a "data not writable" flag to the registry.
+ ESourceCXX sysSource(e_source_registry_ref_builtin_address_book(m_sourceRegistry), TRANSFER_REF);
+ addressBook->setReadOnly(!e_source_equal(esource, sysSource));
+
+ m_addressBooks.insert(AddressBooks_t::value_type(uid, addressBook));
}
+void ContactsSvcWrapper::removeSource(ESource *esource)
+{
+ const char *uid = e_source_get_uid(esource);
+ AddressBooks_t::const_iterator it = m_addressBooks.find(uid);
+ if (it != m_addressBooks.end())
+ m_addressBooks.erase(it);
+ }
+
+#else // FEATURE_EBOOK
+
int ContactsSvcWrapper::size() const
{
return m_idMap.size();
m_addressBooks->push_back(addressBook);
}
+#endif // FEATURE_EBOOK
+
} // Contact
} // DeviceAPI
#include <map>
#include <dpl/shared_ptr.h>
#include <dpl/singleton.h>
+#include <contacts.h>
#include "IAddressBook.h"
namespace DeviceAPI {
void init();
void loadAddressBooks();
+#ifdef FEATURE_EBOOK
+ void addSource(ESource *esource);
+ void removeSource(ESource *esource);
+#else
void insert(AddressBookPtr addressBook);
int size() const;
+#endif
private:
bool m_opened;
+#ifdef FEATURE_EBOOK
+ ESourceRegistryCXX m_sourceRegistry;
+ typedef std::map<std::string, AddressBookPtr> AddressBooks_t;
+ AddressBooks_t m_addressBooks;
+#else
AddressBookPtr m_defaultAddressBook;
AddressBookPtr m_unifiedAddressBook;
AddressBookArrayPtr m_addressBooks;
std::map<std::string, int> m_idMap;
+#endif
};
typedef DPL::Singleton<ContactsSvcWrapper> ContactsSvcWrapperSingleton;
virtual void getGroups(const EventAddressBookGetGroupsPtr &event);
virtual std::string getId() const = 0;
- virtual void setId(const std::string &value) = 0;
+ // virtual void setId(const std::string &value) = 0;
virtual std::string getName() const = 0;
virtual void setName(const std::string &value) = 0;
virtual std::string getAccountId() const = 0;
return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
}
- if(!ContactUtility::checkStrIsUInt(id))
- return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "");
+ // See JSAddressBook::remove() - doesn't have be an integer.
+ // if(!ContactUtility::checkStrIsUInt(id))
+ // return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "");
EventAddressBookGetPtr dplEvent(new EventAddressBookGet());
} catch(const NullPointerException& err) {
return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::TYPE_MISMATCH_ERROR, "");
}
- if(!ContactUtility::checkStrIsUInt(contactId))
- return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "");
+ // JS API does not require the ID to be an int. This checks must be done
+ // in the storage layer, if IDs are ints there. AddressBook::OnRequestReceived()
+ // does this, so this check here is redundant for Contacts Service 2 and
+ // incorrect for Evolution Data Server.
+ // if(!ContactUtility::checkStrIsUInt(contactId))
+ // return JSWebAPIErrorFactory::postException(context, exception, JSWebAPIErrorFactory::INVALID_VALUES_ERROR, "");
EventAddressBookRemovePtr dplEvent(new EventAddressBookRemove());
{
LoggerD("entered");
- int errorCode = 0;
contacts_record_h contacts_record = NULL;
- int selfPersonId = 0;
- int personId = 0;
-
Try
{
if(!event->getPersonIdIsSet())
ThrowMsg(InvalidArgumentException, "person id were not set.");
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
string personIdStr = event->getPersonId();
if(!ContactUtility::checkStrIsUInt(personIdStr))
ThrowMsg(InvalidArgumentException, "wrong " );
+ int selfPersonId = 0;
+ int personId = 0;
try {
personId = ContactUtility::strToInt(personIdStr);
selfPersonId = ContactUtility::strToInt(m_id);
ThrowMsg(InvalidArgumentException, "invalid" );
}
- errorCode = contacts_db_get_record(_contacts_person._uri, personId, &contacts_record);
+ int errorCode = contacts_db_get_record(_contacts_person._uri, personId, &contacts_record);
if(errorCode != CONTACTS_ERROR_NONE)
{
contacts_record_destroy(contacts_record, true);
event->setResult(true);
event->setExceptionCode(ExceptionCodes::None);
+#endif
}
Catch (InvalidArgumentException)
{
{
LoggerD("entered");
- int errorCode = 0;
- int selfPersonId;
- int contactId;
contacts_record_h contacts_record = NULL;
Try
if(!event->getContactIdIsSet())
ThrowMsg(InvalidArgumentException, "contact id were not set.");
+#ifdef FEATURE_EBOOK
+ event->setResult(false);
+ event->setExceptionCode(ExceptionCodes::UnsupportedException);
+ return;
+#else
string contactIdStr = event->getContactId();
if(!ContactUtility::checkStrIsUInt(contactIdStr))
ThrowMsg(InvalidArgumentException, "wrong" );
+ int selfPersonId;
+ int contactId;
try {
selfPersonId = ContactUtility::strToInt(m_id);
contactId = ContactUtility::strToInt(contactIdStr);
ThrowMsg(InvalidArgumentException, "invalid" );
}
- errorCode = contacts_db_get_record(_contacts_simple_contact._uri, contactId, &contacts_record);
+ int errorCode = contacts_db_get_record(_contacts_simple_contact._uri, contactId, &contacts_record);
if(errorCode != CONTACTS_ERROR_NONE)
{
contacts_record_destroy(contacts_record, true);
}
int newPersonId = 0;
- int errorCode = contacts_person_unlink_contact(selfPersonId, contactId, &newPersonId);
+ errorCode = contacts_person_unlink_contact(selfPersonId, contactId, &newPersonId);
if(errorCode == CONTACTS_ERROR_INVALID_PARAMETER)
ThrowMsg(NotFoundException, "Error during executing contacts_person_unlink_contact()");
else if (errorCode != CONTACTS_ERROR_NONE)
event->setResult(true);
event->setExceptionCode(ExceptionCodes::None);
+#endif
}
Catch (InvalidArgumentException)
{
return;
}
- if(contacts_record != NULL)
+ if(contacts_record)
contacts_record_destroy(contacts_record, true);
}
using namespace DeviceAPI::Tizen;
using namespace std;
+#ifndef FEATURE_EBOOK
+
map<string, PersonSearchEngine::FilterPropertyStruct> PersonSearchEngine::attrEnumMap = {
{"id", { _contacts_person.id, PrimitiveType_Long } },
{"displayName", { _contacts_person.display_name, PrimitiveType_String } },
}
}
+#endif // FEATURE_EBOOK
+
} // Contact
} // DeviceAPI
namespace DeviceAPI {
namespace Contact {
+#ifndef FEATURE_EBOOK
+
class PersonSearchEngine :
public DeviceAPI::Tizen::IFilterVisitor,
public DPL::EnableSharedFromThis<PersonSearchEngine>
typedef DPL::SharedPtr<PersonSearchEngine> PersonSearchEnginePtr;
+#endif // FEATURE_EBOOK
+
} // Contact
} // DeviceAPI
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2011-2013 Intel
+//
+// 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.
+//
+
+//
+// This code simplifies using glib C APIs by providing RAII classes
+// and boost::function callbacks for GObject signals.
+//
+// The code was originally written for the SyncEvolution project,
+// where it was published by Intel under the LGPL 2.1. Intel is the sole
+// copyright owner and publishes it here under the Apache license as
+// indicated above.
+//
+
+#ifndef _PLATFORM_CONTACT_CONTACTS2EBOOK_GLIB_SUPPORT_H_
+#define _PLATFORM_CONTACT_CONTACTS2EBOOK_GLIB_SUPPORT_H_
+
+#include <glib.h>
+
+#include <boost/shared_ptr.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <boost/utility.hpp>
+#include <boost/foreach.hpp>
+#include <boost/function.hpp>
+#include <boost/bind.hpp>
+
+#include <iterator>
+#include <memory>
+
+namespace DeviceAPI {
+namespace Contact {
+namespace EBook {
+
+// Signal callback. Specializations will handle varying number of parameters.
+template<class S> struct GObjectSignalHandler {
+ // static void handler();
+ // No specialization defined for the requested function prototype.
+};
+
+template<> struct GObjectSignalHandler<void ()> {
+ static void handler(gpointer data) throw () {
+ (*reinterpret_cast< boost::function<void ()> *>(data))();
+ }
+};
+template<class A1> struct GObjectSignalHandler<void (A1)> {
+ static void handler(A1 a1, gpointer data) throw () {
+ (*reinterpret_cast< boost::function<void (A1)> *>(data))(a1);
+ }
+};
+template<class A1, class A2> struct GObjectSignalHandler<void (A1, A2)> {
+ static void handler(A1 a1, A2 a2, gpointer data) throw () {
+ (*reinterpret_cast< boost::function<void (A1, A2)> *>(data))(a1, a2);
+ }
+};
+template<class A1, class A2, class A3> struct GObjectSignalHandler<void (A1, A2, A3)> {
+ static void handler(A1 a1, A2 a2, A3 a3, gpointer data) throw () {
+ (*reinterpret_cast< boost::function<void (A1, A2, A3)> *>(data))(a1, a2, a3);
+ }
+};
+template<class A1, class A2, class A3, class A4> struct GObjectSignalHandler<void (A1, A2, A3, A4)> {
+ static void handler(A1 a1, A2 a2, A3 a3, A4 a4, gpointer data) throw () {
+ (*reinterpret_cast< boost::function<void (A1, A2, A3, A4)> *>(data))(a1, a2, a3, a4);
+ }
+};
+template<class A1, class A2, class A3, class A4, class A5> struct GObjectSignalHandler<void (A1, A2, A3, A4, A5)> {
+ static void handler(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, gpointer data) throw () {
+ (*reinterpret_cast< boost::function<void (A1, A2, A3, A4, A5)> *>(data))(a1, a2, a3, a4, a5);
+ }
+};
+template<class A1, class A2, class A3, class A4, class A5, class A6> struct GObjectSignalHandler<void (A1, A2, A3, A4, A5, A6)> {
+ static void handler(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, gpointer data) throw () {
+ (*reinterpret_cast< boost::function<void (A1, A2, A3, A4, A5, A6)> *>(data))(a1, a2, a3, a4, a5, a6);
+ }
+};
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7> struct GObjectSignalHandler<void (A1, A2, A3, A4, A5, A6, A7)> {
+ static void handler(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, gpointer data) throw () {
+ (*reinterpret_cast< boost::function<void (A1, A2, A3, A4, A5, A6, A7)> *>(data))(a1, a2, a3, a4, a5, a6, a7);
+ }
+};
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8> struct GObjectSignalHandler<void (A1, A2, A3, A4, A5, A6, A7, A8)> {
+ static void handler(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, gpointer data) throw () {
+ (*reinterpret_cast< boost::function<void (A1, A2, A3, A4, A5, A6, A7, A8)> *>(data))(a1, a2, a3, a4, a5, a6, a7, a8);
+ }
+};
+template<class A1, class A2, class A3, class A4, class A5, class A6, class A7, class A8, class A9> struct GObjectSignalHandler<void (A1, A2, A3, A4, A5, A6, A7, A8, A9)> {
+ static void handler(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, gpointer data) throw () {
+ (*reinterpret_cast< boost::function<void (A1, A2, A3, A4, A5, A6, A7, A8, A9)> *>(data))(a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ }
+};
+
+enum RefOwnership
+{
+ TRANSFER_REF = false, /**<
+ * Create new smart pointer which steals an existing reference without
+ * increasing the reference count of the object.
+ */
+ ADD_REF = true /**<
+ * Create new smart pointer which increases the reference count when
+ * storing the pointer to the object.
+ */
+};
+
+
+template<class C> class TrackGObject : public boost::intrusive_ptr<C> {
+ typedef boost::intrusive_ptr<C> Base_t;
+
+ // Frees the instance of boost::function which was allocated
+ // by connectSignal.
+ template<class S> static void signalDestroy(gpointer data, GClosure *closure) throw () {
+ delete reinterpret_cast< boost::function<void ()> *>(data);
+ }
+
+ public:
+ typedef C PlainC_t;
+
+ TrackGObject(C *ptr, RefOwnership ownership) : Base_t(ptr, (bool)ownership) {}
+ TrackGObject() {}
+ TrackGObject(const TrackGObject &other) : Base_t(other) {}
+ operator C * () const { return Base_t::get(); }
+ operator bool () const { return Base_t::get() != NULL; }
+ C * ref() const { return static_cast<C *>(g_object_ref(Base_t::get())); }
+ void take(C *ptr) { *this = steal(ptr); }
+
+ static TrackGObject steal(C *ptr) { return TrackGObject(ptr, TRANSFER_REF); }
+
+ template<class S> guint connectSignal(const char *signal,
+ const boost::function<S> &callback) {
+ return g_signal_connect_data(Base_t::get(), signal,
+ G_CALLBACK(&GObjectSignalHandler<S>::handler),
+ new boost::function<S>(callback),
+ &signalDestroy<S>,
+ GConnectFlags(0));
+ }
+ void disconnectSignal(guint handlerID) {
+ g_signal_handler_disconnect(static_cast<gpointer>(Base_t::get()),
+ handlerID);
+ }
+};
+
+template<class C> class StealGObject : public TrackGObject<C> {
+ public:
+ StealGObject(C *ptr) : TrackGObject<C>(ptr, TRANSFER_REF) {}
+ StealGObject() {}
+ StealGObject(const StealGObject &other) : TrackGObject<C>(other) {}
+};
+
+template<class C> class TrackGLib : public boost::intrusive_ptr<C> {
+ typedef boost::intrusive_ptr<C> Base_t;
+
+ public:
+ typedef C PlainC_t;
+
+ TrackGLib(C *ptr, RefOwnership ownership) : Base_t(ptr, (bool)ownership) {}
+ TrackGLib() {}
+ TrackGLib(const TrackGLib &other) : Base_t(other) {}
+ operator C * () const { return Base_t::get(); }
+ operator bool () const { return Base_t::get() != NULL; }
+ C * ref() const { return static_cast<C *>(g_object_ref(Base_t::get())); }
+ void take(C *ptr) { *this = steal(ptr); }
+
+ static TrackGLib steal(C *ptr) { return TrackGLib(ptr, TRANSFER_REF); }
+};
+
+template<class C> class StealGLib : public TrackGLib<C> {
+ public:
+ StealGLib(C *ptr) : TrackGLib<C>(ptr, TRANSFER_REF) {}
+ StealGLib() {}
+ StealGLib(const StealGLib &other) : TrackGLib<C>(other) {}
+};
+
+/**
+ * Defines a shared pointer for a GObject-based type, with intrusive
+ * reference counting. Use inside DeviceAPI::Contact::EBook namespace
+ * This is necessary because some functions must be put into the boost
+ * namespace. The type itself is *inside* namespace.
+ *
+ * connectSignal() connects a GObject signal to a boost::function with
+ * the function signature S. Returns the handler ID, which can be
+ * passed to g_signal_handler_disconnect() to remove the connection.
+ *
+ * Example:
+ * SE_GOBJECT_TYPE(GFile)
+ * SE_GOBJECT_TYPE(GObject)
+ *
+ * // reference normally increased during construction,
+ * // steal() avoids that
+ * GFileCXX filecxx = GFileCXX::steal(g_file_new_for_path("foo"));
+ * GFile *filec = filecxx.get(); // does not increase reference count
+ * // file freed here as filecxx gets destroyed
+ *
+ * GObjectCXX object(...);
+ * // Define signature explicitly because it cannot be guessed from
+ * // boost::bind() result.
+ * object.connectSignal<void (GObject *gobject, GParamSpec *pspec)>("notify",
+ * boost::bind(...));
+ * // Signature is taken from boost::function parameter.
+ * guint handlerID =
+ * object.connectSignal("notify",
+ * boost::function<void (GObject *, GParamSpec *)>(boost::bind(...)));
+ * object.disconnectSignal(handlerID);
+ * SE_END_CXX
+ */
+#define SE_GOBJECT_TYPE(_x) \
+ } } } \
+ void inline intrusive_ptr_add_ref(_x *ptr) { g_object_ref(ptr); } \
+ void inline intrusive_ptr_release(_x *ptr) { g_object_unref(ptr); } \
+ namespace DeviceAPI { namespace Contact { namespace EBook { \
+ typedef TrackGObject<_x> _x ## CXX; \
+ typedef StealGObject<_x> _x ## StealCXX; \
+
+/**
+ * Defines a CXX smart pointer similar to SE_GOBJECT_TYPE,
+ * but for types which have their own _ref and _unref
+ * calls.
+ *
+ * Example:
+ * SE_GLIB_TYPE(GMainLoop, g_main_loop)
+ */
+#define SE_GLIB_TYPE(_x, _func_prefix) \
+ } } } \
+ void inline intrusive_ptr_add_ref(_x *ptr) { _func_prefix ## _ref(ptr); } \
+ void inline intrusive_ptr_release(_x *ptr) { _func_prefix ## _unref(ptr); } \
+ namespace DeviceAPI { namespace Contact { namespace EBook { \
+ typedef TrackGLib<_x> _x ## CXX; \
+ typedef StealGLib<_x> _x ## StealCXX; \
+
+/**
+ * Wraps GError. Where a GError** is expected, simply pass
+ * a GErrorCXX instance.
+ */
+struct GErrorCXX {
+ GError *m_gerror;
+
+ /** empty error, NULL pointer */
+ GErrorCXX() : m_gerror(NULL) {}
+
+ /** copies error content */
+ GErrorCXX(const GErrorCXX &other) : m_gerror(g_error_copy(other.m_gerror)) {}
+ GErrorCXX &operator =(const GErrorCXX &other) {
+ if (m_gerror != other.m_gerror) {
+ if (m_gerror) {
+ g_clear_error(&m_gerror);
+ }
+ if (other.m_gerror) {
+ m_gerror = g_error_copy(other.m_gerror);
+ }
+ }
+ return *this;
+ }
+ GErrorCXX &operator =(const GError* err) {
+ if (err != m_gerror) {
+ if (m_gerror) {
+ g_clear_error(&m_gerror);
+ }
+ if (err) {
+ m_gerror = g_error_copy(err);
+ }
+ }
+ return *this;
+ }
+
+ /** takes over ownership */
+ void take (GError *err) {
+ if (err != m_gerror) {
+ if (m_gerror) {
+ g_clear_error(&m_gerror);
+ }
+ m_gerror = err;
+ }
+ }
+
+ /** For convenient access to GError members (message, domain, ...) */
+ const GError * operator-> () const { return m_gerror; }
+
+ /**
+ * For passing to C functions. They must not free the GError,
+ * because GErrorCXX retains ownership.
+ */
+ operator const GError * () const { return m_gerror; }
+
+ /** error description, with fallback if not set (not expected, so not localized) */
+ operator const char * () const { return msg(); }
+ const char *msg() const { return m_gerror ? m_gerror->message : "<<no error>>"; }
+
+ /** clear error */
+ ~GErrorCXX() { g_clear_error(&m_gerror); }
+
+ /** clear error if any is set */
+ void clear() { g_clear_error(&m_gerror); }
+
+ /** transfer ownership of error back to caller */
+ GError *release() { GError *gerror = m_gerror; m_gerror = NULL; return gerror; }
+
+ /** checks whether the current error is the one passed as parameters */
+ bool matches(GQuark domain, gint code) { return g_error_matches(m_gerror, domain, code); }
+
+ /**
+ * Use this when passing GErrorCXX instance to C functions which need to set it.
+ * Make sure the pointer isn't set yet (new GErrorCXX instance, reset if
+ * an error was encountered before) or the GNOME functions will complain
+ * when overwriting the existing error.
+ */
+ operator GError ** () { return &m_gerror; }
+
+ /** true if error set */
+ operator bool () { return m_gerror != NULL; }
+
+ /**
+ * always throws an exception, including information from GError if available:
+ * <action>: <error message>|failure
+ */
+ void throwError(const std::string &action);
+ static void throwError(const std::string &action, const GError *err);
+};
+
+template<class T> void NoopDestructor(T *) {}
+template<class T> void GObjectDestructor(T *ptr) { g_object_unref(ptr); }
+template<class T> void GFreeDestructor(T *ptr) { g_free(static_cast<void *>(ptr)); }
+
+/**
+ * Wraps a G[S]List of pointers to a specific type.
+ * Can be used with boost::FOREACH and provides forward iterators
+ * (two-way iterators and reverse iterators also possible, but not implemented).
+ * Frees the list and optionally (not turned on by default) also frees
+ * the data contained in it, using the provided destructor class.
+ * Use GObjectDestructor for GObject instances.
+ *
+ * Can be swapped, but not copied.
+ *
+ * @param T the type of the instances pointed to inside the list
+ * @param L GList or GSList
+ * @param D destructor function freeing a T instance
+ * @param d destroy list itself (D still gets called even if false)
+ */
+ template< class T, class L, void (*D)(T*) = NoopDestructor<T>, bool d = true> struct GListCXX : boost::noncopyable {
+ L *m_list;
+
+ static void listFree(GSList *l) { g_slist_free(l); }
+ static void listFree(GList *l) { g_list_free(l); }
+
+ static GSList *listPrepend(GSList *list, T *entry) { return g_slist_prepend(list, (gpointer)entry); }
+ static GList *listPrepend(GList *list, T *entry) { return g_list_prepend(list, (gpointer)entry); }
+
+ static GSList *listAppend(GSList *list, T *entry) { return g_slist_append(list, (gpointer)entry); }
+ static GList *listAppend(GList *list, T *entry) { return g_list_append(list, (gpointer)entry); }
+
+ public:
+ typedef T * value_type;
+
+ /** by default initialize an empty list; if parameter is not NULL,
+ owership is transferred to the new instance of GListCXX */
+ GListCXX(L *list = NULL) : m_list(list) {}
+
+ /** free list */
+ ~GListCXX() { clear(); }
+
+ /** free old content, take owership of new one */
+ void reset(L *list = NULL) {
+ clear();
+ m_list = list;
+ }
+
+ /** relinquish ownership of content */
+ L *release() { L *list = m_list; m_list = NULL; return list; }
+
+ /** swap content with other list */
+ void swap(GListCXX &other) { std::swap(m_list, other.m_list); }
+
+ bool empty() { return m_list == NULL; }
+ operator bool () { return !empty(); }
+
+ /** free list */
+ void clear() {
+ BOOST_FOREACH(T *entry, *this) {
+ D(entry);
+ }
+ if (d) {
+ listFree(m_list);
+ }
+ m_list = NULL;
+ }
+
+ /**
+ * Use this when passing GListCXX instance to C functions which need to set it.
+ * Make sure the pointer isn't set yet (new GListCXX instance or cleared).
+ */
+ operator L ** () { return &m_list; }
+
+ /**
+ * Cast to plain G[S]List, for use in functions which do not modify the list.
+ */
+ operator L * () { return m_list; }
+
+ class iterator : public std::iterator<std::forward_iterator_tag, T *> {
+ L *m_entry;
+ public:
+ iterator(L *list = NULL) : m_entry(list) {}
+ iterator(const iterator &other) : m_entry(other.m_entry) {}
+ /**
+ * boost::foreach needs a reference as return code here,
+ * which forces us to do type casting on the address of the void * pointer,
+ * then dereference the pointer. The reason is that typecasting the
+ * pointer value directly yields an rvalue, which can't be used to initialize
+ * the reference return value.
+ */
+ T * &operator -> () const { return *getEntryPtr(); }
+ T * &operator * () const { return *getEntryPtr(); }
+ iterator & operator ++ () { m_entry = m_entry->next; return *this; }
+ iterator operator ++ (int) { return iterator(m_entry->next); }
+ bool operator == (const iterator &other) { return m_entry == other.m_entry; }
+ bool operator != (const iterator &other) { return m_entry != other.m_entry; }
+
+ private:
+ /**
+ * Used above, necessary to hide the fact that we do type
+ * casting tricks. Otherwise the compiler will complain about
+ * *(T **)&m_entry->data with "dereferencing type-punned
+ * pointer will break strict-aliasing rules".
+ *
+ * That warning is about breaking assumptions that the compiler
+ * uses for optimizations. The hope is that those optimzations
+ * aren't done here, and/or are disabled by using a function.
+ */
+ T** getEntryPtr() const { return (T **)&m_entry->data; }
+ };
+ iterator begin() { return iterator(m_list); }
+ iterator end() { return iterator(NULL); }
+
+ class const_iterator : public std::iterator<std::forward_iterator_tag, T *> {
+ L *m_entry;
+ T *m_value;
+
+ public:
+ const_iterator(L *list = NULL) : m_entry(list) {}
+ const_iterator(const const_iterator &other) : m_entry(other.m_entry) {}
+ T * &operator -> () const { return *getEntryPtr(); }
+ T * &operator * () const { return *getEntryPtr(); }
+ const_iterator & operator ++ () { m_entry = m_entry->next; return *this; }
+ const_iterator operator ++ (int) { return const_iterator(m_entry->next); }
+ bool operator == (const const_iterator &other) { return m_entry == other.m_entry; }
+ bool operator != (const const_iterator &other) { return m_entry != other.m_entry; }
+
+ private:
+ T** getEntryPtr() const { return (T **)&m_entry->data; }
+ };
+
+ const_iterator begin() const { return const_iterator(m_list); }
+ const_iterator end() const { return const_iterator(NULL); }
+
+ void push_back(T *entry) { m_list = listAppend(m_list, entry); }
+ void push_front(T *entry) { m_list = listPrepend(m_list, entry); }
+};
+
+/** use this for a list which owns the strings it points to */
+typedef GListCXX<char, GList, GFreeDestructor<char> > GStringListFreeCXX;
+/** use this for a list which does not own the strings it points to */
+typedef GListCXX<char, GList> GStringListNoFreeCXX;
+
+/**
+ * Wraps a C gchar array and takes care of freeing the memory.
+ */
+class PlainGStr : public boost::shared_ptr<gchar>
+{
+ public:
+ PlainGStr() {}
+ PlainGStr(gchar *str) : boost::shared_ptr<char>(str, g_free) {}
+ PlainGStr(const PlainGStr &other) : boost::shared_ptr<gchar>(other) {}
+ PlainGStr(const boost::shared_ptr<gchar> &other) : boost::shared_ptr<gchar>(other) {}
+ // can return NULL
+ gchar *get() const { return (*this) ? &**this : NULL; }
+ operator gchar *() const { return get(); }
+
+ // Never NULL.
+ const gchar *c_str() const { const gchar *res = get(); return res ? res : ""; }
+
+ // Disambiguate bool operator.
+ operator bool () const { return (bool)*(boost::shared_ptr<gchar> *)this; }
+};
+
+/**
+ * Wraps a glib string array, frees with g_strfreev().
+ */
+class PlainGStrArray : public boost::shared_ptr<gchar *>
+{
+ public:
+ PlainGStrArray() {}
+ PlainGStrArray(gchar **array) : boost::shared_ptr<char *>(array, g_strfreev) {}
+ PlainGStrArray(const PlainGStrArray &other) : boost::shared_ptr<char *>(other) {}
+ operator gchar * const *() const { return &**this; }
+ gchar * &at(size_t index) { return get()[index]; }
+ private:
+ // Hide this operator because boost::shared_ptr has problems with it,
+ // probably because of missing traits for a pointer type. Instead use
+ // at().
+ gchar * operator[] (size_t index);
+};
+
+} // EBook
+} // Contact
+} // DeviceAPI
+
+#endif // _PLATFORM_CONTACT_CONTACTS2EBOOK_CONTACTS_H_
--- /dev/null
+Tizen Contact API using Evolution Data Server (EDS)
+===================================================
+
+Implementation
+--------------
+
+The implementation tries to reuse as much of the existing code as
+possible, for two reason:
+* stay as close as possible to the original semantic; in particular,
+ the JavaScript binding is identical
+* avoid forking
+
+As often as possible, constructs like contacts_contact_h in the
+contacts service are reimplemented to avoid ifdefs. A custom
+"contacts.h" in this directory provides that.
+
+The new code uses smart handles for plain C objects and resources,
+using a boost and template based C++ binding for glib which originates
+in the SyncEvolution project. Therefore it is automatically exception
+safe, in contrast to the old code, which relied on manual resource
+tracking.
+
+Because contacts_contact_h and contacts_list_h are no longer plain
+pointers, some code in the plugin which only worked for plain pointers had
+to be changed so that it works for both plain pointers and smart pointers:
+* contacts_list_h contacts = NULL => contacts_list_h contacts(NULL)
+* if (contact_record == NULL) => if (!contact_record)
+
+TODO: #define CONTACTS_ERROR_NONE 0 + remove ifdef in ResultCallback
+TODO: to vCard 2.1
+
+However, several concepts are too different to be handled without ifdefs:
+* access to contact properties
+* IDs: they are strings in EDS, integers in contacts service; to get
+ tests running which assumed "0" as ID of the system address book,
+ "0" is mapped to EDS' "system-address-book" by the plugin. The tests
+ are incorrect in that regard, but it is better to stay closer to the
+ original implementation if possible because apps might make similar
+ assumptions.
+
+Sometimes variable instantiation had to moved into the ifdef sections
+to avoid compiler warnings when these variables were not in use.
+
+Searching is implemented using a different philosophy. With contacts
+service, the plugin implements some of the semantic itself by running
+multiple queries and combining the results. With EDS, the JavaScript
+query is translated into a single database query. This is faster, but
+less accurate.
+
+The EDS version of the plugin supports dynamic creation and deletion
+of address books, in contrast to the contacts service one where the
+list of address books iss only populated once when the JavaScript app
+starts up.
+
+The display name of a contact is hard-coded to the EDS file-as
+extended property (usually not set), full name = "Last name, first
+name" (unless explicity set via FN when importing a contact), org unit
+or first email address. Sorting is also hard-coded, however it is
+limited to last name and first name as tie-breaker because the display
+name is not (currently) available as key for sorting.
+
+TODO (?): add E_CONTACT_NAME_OR_ORG as summary field in EDS and use it
+for sorting.
+
+Usage
+-----
+
+The choice between EDS and contacts service must be made at compile
+time. Invoke cmake with -DWITH_EBOOK=YES to enable EDS. A profile must
+set the bcond wrt_option_eds to enable EDS. Default is always contacts
+service.
+
+Debugging
+---------
+
+Enable the "#if 0 // DEBUG-CONTACTS" section in ContactsSvsWrapper.cpp
+while compiling (has to be done by editing the source), then create
+/tmp/debug-contacts to cause the plugin to wait 10 seconds when
+starting up. /tmp/contacts-wrt.pid contains the process ID of the
+waiting process.
+
+Use for example like this:
+$ touch /tmp/debug-contacts && rm -f /tmp/contacts-wrt.pid
+$ <start test> &
+$ while [ ! -e /tmp/contacts-wrt.pid ]; do : ; done; gdb -p `cat /tmp/contacts-wrt.pid`
+
+Limitations
+-----------
+
+The "Person" and "unified address book" concept and all methods
+related to them in the "tizen.contact" API is not supported. Contacts
+have a fake personId, but it cannot be used for anything.
+
+Contact groups are not supported.
+
+The "EXACTLY" match mode is not supported and silently executed like a
+case insensitive FULLSTRING search. EDS implements that operation and
+the suffix/prefix searches also accent insensitive.
+
+Value range matches and non-string value matches are not supported.
+
+Searching for address values is not supported.
+
+Only a single birthday is support, generic anniversaries are not.
+
+Phonetic names are not supported.
+
+Org information is limited to one company, unit, title, role and
+assistant.
+
+Only one note is supported.
+
+URLs and nicknames are not supported. They could be mapped to certain
+EDS vCard extensions.
+
+A contact cannot be marked as favorite. There is no ringtone property.
+
+When a JavaScript app tries to store unsupported values, storing
+silently drops the unsupported values.
--- /dev/null
+//
+// Tizen Web Device API
+// Copyright (c) 2013 Intel
+//
+// 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.
+//
+
+//
+// This file minimizes ifdefs in the rest of the code by providing:
+// - a replacement for the original contacts.h from contacts-service2
+// - a mapping from some symbols in that file to replacements
+//
+// This file only gets included when compiling against libebook instead
+// of contacts-service2.
+
+#ifndef _PLATFORM_CONTACT_CONTACTS2EBOOK_CONTACTS_H_
+#define _PLATFORM_CONTACT_CONTACTS2EBOOK_CONTACTS_H_
+
+#include <libebook/libebook.h>
+#include <libedataserver/libedataserver.h>
+#include <glib.h>
+
+#include <dpl/noncopyable.h>
+
+#include "GLibSupport.h"
+
+namespace DeviceAPI {
+namespace Contact {
+namespace EBook {
+
+SE_GOBJECT_TYPE(EContact)
+SE_GOBJECT_TYPE(EBookClient)
+SE_GLIB_TYPE(EBookQuery, e_book_query)
+SE_GOBJECT_TYPE(EBookClientView)
+SE_GOBJECT_TYPE(ESource)
+SE_GOBJECT_TYPE(ESourceRegistry)
+SE_GOBJECT_TYPE(EBookClientCursor)
+
+typedef GListCXX<char, GSList, GFreeDestructor<char> > UIDList;
+typedef GListCXX<ESource, GList, GObjectDestructor<ESource> >ESourceList;
+
+enum {
+ CONTACTS_ERROR_NONE
+};
+
+enum contacts_match_str_flag_e {
+ CONTACTS_MATCH_EXISTS,
+ CONTACTS_MATCH_EXACTLY,
+ CONTACTS_MATCH_FULLSTRING,
+ CONTACTS_MATCH_CONTAINS,
+ CONTACTS_MATCH_STARTSWITH,
+ CONTACTS_MATCH_ENDSWITH
+};
+
+enum contacts_match_int_flag_e {
+ CONTACTS_MATCH_GREATER_THAN_OR_EQUAL,
+ CONTACTS_MATCH_LESS_THAN_OR_EQUAL,
+ CONTACTS_MATCH_EQUAL
+};
+
+template <class T> class Handle : public T
+{
+ public:
+ // For contacts_record_h contacts_record = NULL
+ Handle(void * = NULL) {}
+ Handle(typename T::PlainC_t *object, RefOwnership ownership) : T(object, ownership) {}
+ Handle(const Handle &other) : T(other) {}
+};
+
+
+class ContactsListHandle
+{
+};
+
+class ContactsQueryHandle
+{
+};
+
+class ContactsFilterHandle
+{
+};
+
+typedef Handle<EContactCXX> contacts_record_h;
+static inline void contacts_record_destroy(contacts_record_h &handle, bool) { handle.reset(); }
+
+typedef GListCXX<EContact, GSList, GObjectDestructor<EContact> > contacts_list_h;
+
+static inline int contacts_list_create(contacts_list_h *list) { return CONTACTS_ERROR_NONE; }
+static inline int contacts_list_destroy(contacts_list_h &list, bool) { list.clear(); return CONTACTS_ERROR_NONE; }
+static inline int contacts_list_add(contacts_list_h &list, const contacts_record_h &contact) { list.push_front((EContact *)g_object_ref(contact)); return CONTACTS_ERROR_NONE; }
+
+
+// Helper C++ code for type-safe access to EContact fields.
+template<EContactField field> struct EContactTraits;
+struct EContactStringType {
+ typedef char type;
+ static void free(char *ptr) { g_free(ptr); }
+};
+struct EContactDateType {
+ typedef EContactDate type;
+ static void free(EContactDate *ptr) { e_contact_date_free(ptr); }
+};
+template<> struct EContactTraits<E_CONTACT_REV> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_UID> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_BOOK_UID> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_NAME_OR_ORG> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_ORG> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_ORG_UNIT> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_OFFICE> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_TITLE> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_ROLE> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_MANAGER> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_ASSISTANT> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_NOTE> : public EContactStringType {};
+template<> struct EContactTraits<E_CONTACT_PHOTO> {
+ typedef EContactPhoto type;
+ static void free(EContactPhoto *ptr) { e_contact_photo_free(ptr); }
+};
+template<> struct EContactTraits<E_CONTACT_NAME> {
+ typedef EContactName type;
+ static void free(EContactName *ptr) { e_contact_name_free(ptr); }
+};
+template<> struct EContactTraits<E_CONTACT_BIRTH_DATE> : public EContactDateType {};
+template<> struct EContactTraits<E_CONTACT_ANNIVERSARY> : public EContactDateType {};
+template<EContactField field> struct EContactFieldCXX {
+ static boost::shared_ptr<typename EContactTraits<field>::type> get(EContact *contact) {
+ return boost::shared_ptr<typename EContactTraits<field>::type>(static_cast<typename EContactTraits<field>::type *>(e_contact_get(contact, field)),
+ free);
+ }
+ static void set(EContact *contact, const typename EContactTraits<field>::type *value) {
+ e_contact_set(contact, field, value);
+ }
+ static void setString(EContact *contact, const std::string &value, bool isSet) {
+ set(contact, isSet ? value.c_str() : NULL);
+ }
+};
+
+
+typedef EBookQueryCXX contacts_query_h;
+
+// not supported
+typedef void * contacts_filter_h;
+
+} // EBook
+} // Contact
+} // DeviceAPI
+
+using namespace DeviceAPI::Contact::EBook;
+
+#endif // _PLATFORM_CONTACT_CONTACTS2EBOOK_CONTACTS_H_