📄 svexservice.cpp
字号:
// Copyright (c) 2006 Murray Read, All rights reserved
#include "SvexService.h"
#include "SvexService.hrh"
#include "SvexUtil.h"
#include <barsread2.h>
// The IPC message ids used in the Service Info Service.
// These messages ids should always be >= KServiceCmdBase
// to avoid conflicts with system messages.
enum TSvexServiceCmd
{
ESvexServiceCmdShowAll = RApaAppServiceBase::KServiceCmdBase,
ESvexServiceCmdShowApp
};
//
// RSvexServiceInfo
//
EXPORT_C void RSvexServiceInfo::ShowAllL(TUid aServiceUid)
{
// The ShowAll message sends the service UID to the server app
User::LeaveIfError(SendReceive(ESvexServiceCmdShowAll,TIpcArgs(aServiceUid.iUid)));
}
EXPORT_C void RSvexServiceInfo::ShowAppL(TUid aServiceUid, TUid aAppUid)
{
// The ShowApp message sends the service UID and an app UID to the server app
User::LeaveIfError(SendReceive(ESvexServiceCmdShowApp,TIpcArgs(aServiceUid.iUid, aAppUid.iUid)));
}
TUid RSvexServiceInfo::ServiceUid() const
{
// The ServiceUid() function must return the correct UID for this service
return TUid::Uid(KSvexServiceInfoServiceUid);
}
//
// CSvexServiceServiceInfo
//
EXPORT_C CSvexServiceServiceInfo* CSvexServiceServiceInfo::NewLC(const CSvexServiceInfo& aInfo)
{
CSvexServiceServiceInfo* self = new(ELeave) CSvexServiceServiceInfo;
CleanupStack::PushL(self);
self->ConstructL(aInfo);
return self;
}
void CSvexServiceServiceInfo::ConstructL(const CSvexServiceInfo& aInfo)
{
// ConstructL builds an array of information about service
// extracted from the registration info of apps supporting
// the Service Info Service.
// Check that the service info passed in matches the Service Info Service.
__ASSERT_ALWAYS(aInfo.ServiceUid().iUid == KSvexServiceInfoServiceUid, Panic(ESvexPanicMustBeServiceInfoService));
// count and reserve space in the array so that AppendL() is efficient.
TInt count = aInfo.MsasiCount();
iInfo.ReserveL(count);
// Add the registration info for each app
for (TInt ii=0; ii<count; ii++)
{
TSvexAppServiceInfo info = aInfo.MsasiAt(ii);
TRAP_IGNORE(AddInfoL(info));
}
if (iInfo.Count() == 0)
User::Leave(KErrNotFound);
}
EXPORT_C void CSvexServiceServiceInfo::ExtractInfoLC(const TSvexAppServiceInfo& aInfo, TUid& aServiceMatched, HBufC*& aName)
{
// extract the registration info from the opaque_data field
// of the service registration resource.
const TDesC8& data = aInfo.iInfo.OpaqueData();
// RResourceReader is a safe way to extract data from 3rd
// party resources. The worst that will happen is a leave.
RResourceReader reader;
reader.OpenLC(data);
aServiceMatched.iUid = reader.ReadInt32L();
aName = reader.ReadHBufCL();
CleanupStack::PopAndDestroy(&reader);
CleanupStack::PushL(aName);
}
void CSvexServiceServiceInfo::AddInfoL(const TSvexAppServiceInfo& aInfo)
{
TUid service;
HBufC* name;
ExtractInfoLC(aInfo, service, name);
SInfo serviceInfo =
{
service.iUid,
aInfo.iAppUid.iUid,
name
};
// This demo uses 0 as a "match anything" service id
if (service.iUid == 0)
iFallback = iInfo.Count();
// AppendL() will be efficient because the space is already reserved
iInfo.AppendL(serviceInfo);
CleanupStack::Pop(name);
}
CSvexServiceServiceInfo::CSvexServiceServiceInfo()
{
}
EXPORT_C CSvexServiceServiceInfo::~CSvexServiceServiceInfo()
{
TInt count = iInfo.Count();
for (TInt ii=0; ii<count; ii++)
delete iInfo[ii].iName;
iInfo.Close();
}
EXPORT_C const TDesC& CSvexServiceServiceInfo::ServiceName(TUid aService) const
{
const SInfo& info = Find(aService);
return *info.iName;
}
EXPORT_C TUid CSvexServiceServiceInfo::InfoApp(TUid aService) const
{
const SInfo& info = Find(aService);
return info.iApp;
}
const CSvexServiceServiceInfo::SInfo& CSvexServiceServiceInfo::Find(TUid aService) const
{
TInt count = iInfo.Count();
for (TInt ii=0; ii<count; ii++)
{
const SInfo& info = iInfo[ii];
if (info.iService == aService)
return info;
}
return iInfo[iFallback];
}
//
// CSvexServiceInfoClient
//
EXPORT_C CSvexServiceInfoClient* CSvexServiceInfoClient::NewAllL(const CSvexServiceInfo& aServiceInfoService, MApaServerAppExitObserver* aObserver, TUid aServiceUid)
{
// create an "All apps" session by construction and sending the ShowAll message
CSvexServiceInfoClient* self = new(ELeave) CSvexServiceInfoClient();
CleanupStack::PushL(self);
self->ConstructL(self->AppForServiceL(aServiceInfoService, aServiceUid), aObserver);
self->iService.ShowAllL(aServiceUid);
CleanupStack::Pop(self);
return self;
}
EXPORT_C CSvexServiceInfoClient* CSvexServiceInfoClient::NewAppL(const CSvexServiceInfo& aServiceInfoService, MApaServerAppExitObserver* aObserver, TUid aServiceUid, TUid aAppUid)
{
// create a "Single app" session by construction and sending the ShowApp message
CSvexServiceInfoClient* self = new(ELeave) CSvexServiceInfoClient();
CleanupStack::PushL(self);
self->ConstructL(self->AppForServiceL(aServiceInfoService, aServiceUid), aObserver);
self->iService.ShowAppL(aServiceUid, aAppUid);
CleanupStack::Pop(self);
return self;
}
EXPORT_C CSvexServiceInfoClient::~CSvexServiceInfoClient()
{
delete iMonitor;
iService.Close();
}
CSvexServiceInfoClient::CSvexServiceInfoClient()
{
}
void CSvexServiceInfoClient::ConstructL(TUid aApp, MApaServerAppExitObserver* aObserver)
{
// Launch and connect the server app as a chained app.
// This will make it appear as if the server app is running
// in the same window group as the client. The window groups
// are in-fact chained.
iService.ConnectChainedAppL(aApp);
// Create a lifetime monitor for the server app
if (aObserver)
iMonitor = CApaServerAppExitMonitor::NewL(iService, *aObserver, CActive::EPriorityStandard);
}
TUid CSvexServiceInfoClient::AppForServiceL(const CSvexServiceInfo& aInfo, TUid aServiceUid)
{
// Find the correct app to show info about a service
CSvexServiceServiceInfo* serviceInfo = CSvexServiceServiceInfo::NewLC(aInfo);
TUid app = serviceInfo->InfoApp(aServiceUid);
CleanupStack::PopAndDestroy(serviceInfo);
return app;
}
//
// CSvexServiceInfoSession
//
EXPORT_C CSvexServiceInfoSession::CSvexServiceInfoSession()
{
}
EXPORT_C CSvexServiceInfoSession::~CSvexServiceInfoSession()
{
}
EXPORT_C void CSvexServiceInfoSession::ServiceL(const RMessage2& aMessage)
{
// The ServiceL function - the heart of the session.
switch (aMessage.Function())
{
case ESvexServiceCmdShowAll:
// Handle the ShowAll message by calling the ShowAllL()
// virtual function with the UID passed in parameter 0.
ShowAllL(TUid::Uid(aMessage.Int0()));
aMessage.Complete(KErrNone);
break;
case ESvexServiceCmdShowApp:
// Handle the ShowApp message by calling the ShowAppL()
// virtual function with the UIDs passed in parameter 0 and 1.
ShowAppL(TUid::Uid(aMessage.Int0()), TUid::Uid(aMessage.Int1()));
aMessage.Complete(KErrNone);
break;
default:
CAknAppServiceBase::ServiceL(aMessage);
break;
}
}
//
// CSvexServiceInfoServer
//
EXPORT_C CSvexServiceInfoServer::~CSvexServiceInfoServer()
{
}
EXPORT_C CApaAppServiceBase* CSvexServiceInfoServer::CreateServiceL(TUid aServiceType) const
{
// When the client has requested the Server Info Service,
// ensure the server returns an implementation of
// CSvexServiceInfoSession
if (aServiceType.iUid == KSvexServiceInfoServiceUid)
return CreateServiceInfoServiceL();
else
return CAknAppServer::CreateServiceL(aServiceType);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -