platform-api-0.20+14.04.20140411/ 0000755 0000153 0177776 00000000000 12322055312 016413 5 ustar pbuser nogroup 0000000 0000000 platform-api-0.20+14.04.20140411/android/ 0000755 0000153 0177776 00000000000 12322055312 020033 5 ustar pbuser nogroup 0000000 0000000 platform-api-0.20+14.04.20140411/android/mock/ 0000755 0000153 0177776 00000000000 12322055312 020764 5 ustar pbuser nogroup 0000000 0000000 platform-api-0.20+14.04.20140411/android/mock/mock.cpp 0000644 0000153 0177776 00000011636 12322054725 022437 0 ustar pbuser nogroup 0000000 0000000 /*
* Copyright © 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* Authored by: Thomas Voß
*/
#include
#include
#include
#include
#include
#include
#include
#include
// C apis
#include
#include
namespace
{
struct MockPhysicalDisplayInfo : public ubuntu::application::ui::PhysicalDisplayInfo
{
MockPhysicalDisplayInfo() {}
int dpi()
{
return 96;
}
int horizontal_resolution()
{
return 1024;
}
int vertical_resolution()
{
return 768;
}
};
struct MockSession : public ubuntu::application::ui::Session
{
MockSession()
{
}
const ubuntu::application::ui::PhysicalDisplayInfo::Ptr& physical_display_info(
ubuntu::application::ui::PhysicalDisplayIdentifier id)
{
static ubuntu::application::ui::PhysicalDisplayInfo::Ptr display(
new MockPhysicalDisplayInfo());
return display;
}
const ubuntu::application::ui::Surface::Ptr& create_surface(
const ubuntu::application::ui::SurfaceProperties& props,
const ubuntu::application::ui::input::Listener::Ptr& listener)
{
(void) props;
(void) listener;
}
const ubuntu::application::ui::Surface::Ptr& destroy_surface(
const ubuntu::application::ui::SurfaceProperties& props)
{
(void) props;
}
EGLNativeDisplayType to_native_display_type()
{
return 0;
}
};
struct MockSessionService : public ubuntu::ui::SessionService
{
MockSessionService()
{
}
const ubuntu::application::ui::Session::Ptr& start_a_new_session(const ubuntu::application::ui::SessionCredentials& cred)
{
(void) cred;
static ubuntu::application::ui::Session::Ptr session(new MockSession());
return session;
}
};
struct MockSurface : public ubuntu::application::ui::Surface
{
MockSurface(const ubuntu::application::ui::input::Listener::Ptr& listener)
: ubuntu::application::ui::Surface(listener)
{
}
bool is_visible() const
{
return true;
}
void set_visible(bool visible)
{
(void) visible;
}
void set_alpha(float alpha)
{
(void) alpha;
}
float alpha() const
{
return 1.f;
}
void move_to(int x, int y)
{
(void) x;
(void) y;
}
void move_by(int dx, int dy)
{
(void) dx;
(void) dy;
}
// Bind to EGL/GL rendering API
EGLNativeWindowType to_native_window_type()
{
return 0;
}
};
struct MockSurfaceFactory : public ubuntu::application::ui::SurfaceFactory
{
ubuntu::application::ui::Surface::Ptr create_surface(
const ubuntu::application::ui::SurfaceProperties& props,
const ubuntu::application::ui::input::Listener::Ptr& listener)
{
static ubuntu::application::ui::Surface::Ptr surface(new MockSurface(listener));
return surface;
}
};
struct MockSetup : public ubuntu::application::ui::Setup
{
ubuntu::application::ui::StageHint stage_hint()
{
return ubuntu::application::ui::main_stage;
}
ubuntu::application::ui::FormFactorHint form_factor_hint()
{
return ubuntu::application::ui::desktop_form_factor;
}
};
}
// We need to inject some platform specific symbols here.
namespace ubuntu
{
namespace application
{
namespace ui
{
const ubuntu::application::ui::SurfaceFactory::Ptr& ubuntu::application::ui::SurfaceFactory::instance()
{
static ubuntu::application::ui::SurfaceFactory::Ptr session(new MockSurfaceFactory());
return session;
}
void init(int argc, char** argv)
{
(void) argc;
(void) argv;
}
const ubuntu::application::ui::Setup::Ptr& ubuntu::application::ui::Setup::instance()
{
static ubuntu::application::ui::Setup::Ptr session(new MockSetup());
return session;
}
}
}
namespace ui
{
const ubuntu::ui::SessionService::Ptr& ubuntu::ui::SessionService::instance()
{
static ubuntu::ui::SessionService::Ptr instance(new MockSessionService());
return instance;
}
}
}
platform-api-0.20+14.04.20140411/android/mock/CMakeLists.txt 0000644 0000153 0177776 00000000446 12322054725 023537 0 ustar pbuser nogroup 0000000 0000000 add_library(
ubuntu_mock_platform SHARED
mock.cpp
# Pull in the default C API implementation on top of the C++ API
../default/default_ubuntu_application_ui.cpp
)
install(
TARGETS ubuntu_mock_platform
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib/static)
platform-api-0.20+14.04.20140411/android/hybris/ 0000755 0000153 0177776 00000000000 12322055312 021333 5 ustar pbuser nogroup 0000000 0000000 platform-api-0.20+14.04.20140411/android/hybris/default_application_manager.h 0000644 0000153 0177776 00000021405 12322054725 027216 0 ustar pbuser nogroup 0000000 0000000 /*
* Copyright © 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* Authored by: Thomas Voß
*/
#ifndef DEFAULT_APPLICATION_MANAGER_H_
#define DEFAULT_APPLICATION_MANAGER_H_
#include "application_manager.h"
#include "default_application_manager_input_setup.h"
#include "default_application_session.h"
#include "event_loop.h"
#include "lifecycle_helpers.h"
#include
#include
#include
#include
#include
#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
#include
#else
#include
#endif
#include
namespace ubuntu { namespace detail
{
struct ApplicationManager :
public android::BnApplicationManager,
public android::IBinder::DeathRecipient
{
static const int default_shell_component_layer = 1000000;
static const int default_dash_layer = default_shell_component_layer + 1;
static const int default_indicator_layer = default_shell_component_layer + 2;
static const int default_notifications_layer = default_shell_component_layer + 3;
static const int default_greeter_layer = default_shell_component_layer + 4;
static const int default_launcher_layer = default_shell_component_layer + 5;
static const int default_osk_layer = default_shell_component_layer + 6;
static const int default_shutdown_dialog_layer = default_shell_component_layer + 7;
static const int focused_application_base_layer = 100;
static const int wallpaper_layer = 0;
static const int non_focused_application_layer = -1;
struct ShellInputSetup : public android::RefBase
{
struct DisplayInfo
{
DisplayInfo();
android::DisplayInfo info;
};
template
struct Window : public android::RefBase
{
static int looper_callback(int receiveFd, int events, void* ctxt);
Window(ShellInputSetup* parent,
int _x = x,
int _y = y,
int _w = w,
int _h = h);
android::sp input_window;
ShellInputSetup* parent;
android::sp server_channel;
android::sp client_channel;
android::InputConsumer input_consumer;
android::PreallocatedInputEventFactory event_factory;
};
ShellInputSetup(const android::sp& input_manager);
bool shell_has_focus;
DisplayInfo display_info;
android::sp input_manager;
android::sp shell_application;
android::sp looper;
ubuntu::application::EventLoop event_loop;
android::KeyedVector > trap_windows;
// TODO(tvoss): Get rid of hard coded values.
Window<0, 0, 720, 1280> event_trap_window;
// TODO(tvoss): This is really hacky, but we need to
// synchronize/reflect state changes across multiple processes
// here, i.e.:
// * maliit-server, which takes care of hiding and showing the osk
// * notify-osd, which takes care of hiding and showing notifications
Window<0, 812, 720, 468> osk_window;
Window<36, 18, 684, 216> notifications_window;
};
class InputFilter : public android::InputFilter
{
public:
InputFilter(ApplicationManager* manager);
bool filter_event(const android::InputEvent* event);
private:
ApplicationManager* manager;
bool handle_key_event(const android::KeyEvent* event);
};
class LockingIterator : public android::RefBase
{
public:
void advance() ;
bool is_valid() const;
void make_current();
const android::sp& operator*();
protected:
friend class ApplicationManager;
LockingIterator(
ApplicationManager* manager,
size_t index);
virtual ~LockingIterator();
private:
ApplicationManager* manager;
size_t it;
};
ApplicationManager();
void update_app_lists();
// From DeathRecipient
void binderDied(const android::wp& who);
void lock();
void unlock();
android::sp iterator();
void session_set_state(const android::sp& session,
int32_t new_state);
void start_a_new_session(
int32_t session_type,
int32_t stage_hint,
const android::String8& app_name,
const android::String8& desktop_file,
const android::sp& session,
int fd,
uint32_t remote_pid);
void register_a_surface(
const android::String8& title,
const android::sp& session,
int32_t surface_role,
int32_t token,
int fd);
void request_fullscreen(const android::sp& session);
void register_an_observer(const android::sp& observer);
void register_task_controller(const android::sp& controller);
int get_session_pid(const android::sp& session);
void request_update_for_session(const android::sp& session);
void focus_running_session_with_id(int id);
void unfocus_running_sessions();
int32_t query_snapshot_layer_for_session_with_id(int id);
android::IApplicationManagerSession::SurfaceProperties query_surface_properties_for_session_id(int id);
void switch_to_well_known_application(int32_t app);
int32_t set_surface_trap(int32_t x, int32_t y, int32_t width, int32_t height);
void unset_surface_trap(int32_t handle);
void report_osk_visible(int32_t x, int32_t y, int32_t width, int32_t height);
void report_osk_invisible();
void report_notification_visible();
void report_notification_invisible();
void switch_focused_application_locked(size_t index_of_next_focused_app);
void switch_focus_to_next_application_locked();
void kill_focused_application_locked();
private:
void update_input_setup_locked();
size_t session_id_to_index(int id);
void notify_observers_about_session_requested(uint32_t app);
void notify_observers_about_session_born(int id, int stage_hint, const android::String8& desktop_file);
void notify_observers_about_session_unfocused(int id, int stage_hint, const android::String8& desktop_file);
void notify_observers_about_session_focused(int id, int stage_hint, const android::String8& desktop_file);
void notify_observers_about_keyboard_geometry_changed(int x, int y, int width, int height);
void notify_observers_about_session_requested_fullscreen(int id, int stage_hint, const android::String8& desktop_file);
void notify_observers_about_session_died(int id, int stage_hint, const android::String8& desktop_file);
android::sp input_listener;
android::sp input_filter;
android::sp input_setup;
android::sp shell_input_setup;
bool is_osk_visible;
bool are_notifications_visible;
android::Condition state_cond;
android::Mutex state_lock;
android::Mutex guard;
android::KeyedVector< android::sp, android::sp > apps;
android::Vector< android::sp > apps_as_added;
android::Mutex observer_guard;
android::Vector< android::sp > app_manager_observers;
android::sp app_manager_task_controller;
size_t focused_application;
size_t side_stage_application;
size_t main_stage_application;
};
}
}
#endif // DEFAULT_APPLICATION_MANAGER_H_
platform-api-0.20+14.04.20140411/android/hybris/application_manager.cpp 0000644 0000153 0177776 00000057641 12322054725 026060 0 ustar pbuser nogroup 0000000 0000000 /*
* Copyright © 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Thomas Voß
*/
#include "application_manager.h"
#include
#include
namespace android
{
IMPLEMENT_META_INTERFACE(ClipboardService, "UbuntuClipboardService");
IMPLEMENT_META_INTERFACE(AMTaskController, "UbuntuApplicationManagerTaskController");
IMPLEMENT_META_INTERFACE(ApplicationManagerObserver, "UbuntuApplicationManagerObserver");
IMPLEMENT_META_INTERFACE(ApplicationManagerSession, "UbuntuApplicationManagerSession");
IMPLEMENT_META_INTERFACE(ApplicationManager, "UbuntuApplicationManager");
IClipboardService::Content::Content() : data(NULL),
data_size(0)
{
}
IClipboardService::Content::Content(
const String8& mime_type,
void* _data,
size_t size) : mime_type(mime_type),
data(malloc(size)),
data_size(size)
{
memcpy(this->data, _data, size);
}
IClipboardService::Content::~Content()
{
if (data != NULL && data_size != 0)
free(data);
}
IClipboardService::Content::Content(const IClipboardService::Content& content)
: mime_type(content.mime_type),
data(malloc(content.data_size)),
data_size(content.data_size)
{
memcpy(data, content.data, data_size);
}
IClipboardService::Content& IClipboardService::Content::operator=(const IClipboardService::Content& content)
{
mime_type = content.mime_type;
data_size = content.data_size;
data = realloc(data, data_size);
memcpy(data, content.data, data_size);
return *this;
}
status_t BnClipboardService::onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags)
{
switch(code)
{
case SET_CLIPBOARD_CONTENT_COMMAND:
{
IClipboardService::Content content;
String8 mime_type = data.readString8();
size_t data_size = data.readInt32();
void* p = malloc(data_size);
data.read(p, data_size);
set_content(Content(mime_type, p, data_size));
free(p);
break;
}
case GET_CLIPBOARD_CONTENT_COMMAND:
{
IClipboardService::Content content;
get_content(content);
reply->writeString8(String8(content.mime_type));
reply->writeInt32(content.data_size);
reply->write(content.data, content.data_size);
}
break;
}
return NO_ERROR;
}
BpClipboardService::BpClipboardService(const sp& impl) : BpInterface(impl)
{
}
void BpClipboardService::set_content(const IClipboardService::Content& content)
{
Parcel in, out;
in.writeString8(String8(content.mime_type));
in.writeInt32(content.data_size);
in.write(content.data, content.data_size);
remote()->transact(
SET_CLIPBOARD_CONTENT_COMMAND,
in,
&out);
}
void BpClipboardService::get_content(IClipboardService::Content& content)
{
Parcel in, out;
remote()->transact(
GET_CLIPBOARD_CONTENT_COMMAND,
in,
&out);
content.mime_type = out.readString8();
content.data_size = out.readInt32();
content.data = malloc(content.data_size);
out.read(content.data, content.data_size);
}
BnApplicationManagerSession::BnApplicationManagerSession()
{
}
BnApplicationManagerSession::~BnApplicationManagerSession() {}
status_t BnApplicationManagerSession::onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags)
{
switch(code)
{
case RAISE_APPLICATION_SURFACES_TO_LAYER_COMMAND:
{
int32_t layer;
data.readInt32(&layer);
raise_application_surfaces_to_layer(layer);
}
break;
case RAISE_SURFACE_TO_LAYER_COMMAND:
{
int32_t token, layer;
token = data.readInt32();
layer = data.readInt32();
raise_surface_to_layer(token, layer);
}
break;
case QUERY_SURFACE_PROPERTIES_FOR_TOKEN_COMMAND:
{
int32_t token = data.readInt32();
IApplicationManagerSession::SurfaceProperties props =
query_surface_properties_for_token(token);
reply->writeInt32(props.layer);
reply->writeInt32(props.left);
reply->writeInt32(props.top);
reply->writeInt32(props.right);
reply->writeInt32(props.bottom);
}
break;
case ON_APPLICATION_STARTED_NOTIFICATION:
{
on_application_resumed();
}
break;
case ON_APPLICATION_ABOUT_TO_STOP_NOTIFICATION:
{
on_application_about_to_stop();
}
break;
}
return NO_ERROR;
}
BpApplicationManagerSession::BpApplicationManagerSession(const sp& impl)
: BpInterface(impl)
{
}
BpApplicationManagerSession::~BpApplicationManagerSession()
{
}
void BpApplicationManagerSession::raise_surface_to_layer(int32_t token, int layer)
{
Parcel in, out;
in.writeInt32(token);
in.writeInt32(layer);
remote()->transact(
RAISE_SURFACE_TO_LAYER_COMMAND,
in,
&out);
}
void BpApplicationManagerSession::raise_application_surfaces_to_layer(int layer)
{
Parcel in, out;
in.writeInt32(layer);
remote()->transact(
RAISE_APPLICATION_SURFACES_TO_LAYER_COMMAND,
in,
&out);
}
IApplicationManagerSession::SurfaceProperties BpApplicationManagerSession::query_surface_properties_for_token(int32_t token)
{
Parcel in, out;
in.writeInt32(token);
remote()->transact(
QUERY_SURFACE_PROPERTIES_FOR_TOKEN_COMMAND,
in,
&out);
IApplicationManagerSession::SurfaceProperties props;
props.layer = out.readInt32();
props.left = out.readInt32();
props.top = out.readInt32();
props.right = out.readInt32();
props.bottom = out.readInt32();
return props;
}
void BpApplicationManagerSession::on_application_resumed()
{
Parcel in, out;
remote()->transact(
ON_APPLICATION_STARTED_NOTIFICATION,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
void BpApplicationManagerSession::on_application_about_to_stop()
{
Parcel in, out;
remote()->transact(
ON_APPLICATION_ABOUT_TO_STOP_NOTIFICATION,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
status_t BnAMTaskController::onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags)
{
switch(code)
{
case CONTINUE_TASK_COMMAND:
{
uint32_t pid = data.readInt32();
continue_task(pid);
break;
}
case SUSPEND_TASK_COMMAND:
{
int pid = data.readInt32();
suspend_task(pid);
break;
}
}
return NO_ERROR;
}
BpAMTaskController::BpAMTaskController(const sp& impl)
: BpInterface(impl)
{
}
void BpAMTaskController::continue_task(uint32_t pid)
{
Parcel in, out;
in.writeInt32(pid);
remote()->transact(
CONTINUE_TASK_COMMAND,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
void BpAMTaskController::suspend_task(uint32_t pid)
{
Parcel in, out;
in.writeInt32(pid);
remote()->transact(
SUSPEND_TASK_COMMAND,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
status_t BnApplicationManagerObserver::onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags)
{
switch(code)
{
case ON_SESSION_REQUESTED_NOTIFICATION:
{
uint32_t app = data.readInt32();
on_session_requested(app);
break;
}
case ON_SESSION_BORN_NOTIFICATION:
{
int id = data.readInt32();
int stage_hint = data.readInt32();
String8 desktop_file = data.readString8();
on_session_born(id, stage_hint, desktop_file);
break;
}
case ON_SESSION_UNFOCUSED_NOTIFICATION:
{
int id = data.readInt32();
int stage_hint = data.readInt32();
String8 desktop_file = data.readString8();
on_session_unfocused(id, stage_hint, desktop_file);
break;
}
case ON_SESSION_FOCUSED_NOTIFICATION:
{
int id = data.readInt32();
int stage_hint = data.readInt32();
String8 desktop_file = data.readString8();
on_session_focused(id, stage_hint, desktop_file);
break;
}
case ON_KEYBOARD_GEOMETRY_CHANGED_NOTIFICATION:
{
int x = data.readInt32();
int y = data.readInt32();
int width = data.readInt32();
int height = data.readInt32();
on_keyboard_geometry_changed(x, y, width, height);
break;
}
case ON_SESSION_REQUESTED_FULLSCREEN_NOTIFICATION:
{
int id = data.readInt32();
int stage_hint = data.readInt32();
String8 desktop_file = data.readString8();
on_session_requested_fullscreen(id, stage_hint, desktop_file);
break;
}
case ON_SESSION_DIED_NOTIFICATION:
{
int id = data.readInt32();
int stage_hint = data.readInt32();
String8 desktop_file = data.readString8();
on_session_died(id, stage_hint, desktop_file);
break;
}
}
return NO_ERROR;
}
BpApplicationManagerObserver::BpApplicationManagerObserver(const sp& impl)
: BpInterface(impl)
{
}
void BpApplicationManagerObserver::on_session_requested(
uint32_t app)
{
Parcel in, out;
in.writeInt32(app);
remote()->transact(
ON_SESSION_REQUESTED_NOTIFICATION,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
void BpApplicationManagerObserver::on_session_born(int id,
int stage_hint,
const String8& desktop_file_hint)
{
Parcel in, out;
in.writeInt32(id);
in.writeInt32(stage_hint);
in.writeString8(desktop_file_hint);
remote()->transact(
ON_SESSION_BORN_NOTIFICATION,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
void BpApplicationManagerObserver::on_session_unfocused(int id,
int stage_hint,
const String8& desktop_file_hint)
{
Parcel in, out;
in.writeInt32(id);
in.writeInt32(stage_hint);
in.writeString8(desktop_file_hint);
remote()->transact(
ON_SESSION_UNFOCUSED_NOTIFICATION,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
void BpApplicationManagerObserver::on_session_focused(int id,
int stage_hint,
const String8& desktop_file_hint)
{
Parcel in, out;
in.writeInt32(id);
in.writeInt32(stage_hint);
in.writeString8(desktop_file_hint);
remote()->transact(
ON_SESSION_FOCUSED_NOTIFICATION,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
void BpApplicationManagerObserver::on_keyboard_geometry_changed(int x,
int y,
int width,
int height)
{
Parcel in, out;
in.writeInt32(x);
in.writeInt32(y);
in.writeInt32(width);
in.writeInt32(height);
remote()->transact(
ON_KEYBOARD_GEOMETRY_CHANGED_NOTIFICATION,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
void BpApplicationManagerObserver::on_session_requested_fullscreen(int id,
int stage_hint,
const String8& desktop_file_hint)
{
Parcel in, out;
in.writeInt32(id);
in.writeInt32(stage_hint);
in.writeString8(desktop_file_hint);
remote()->transact(
ON_SESSION_REQUESTED_FULLSCREEN_NOTIFICATION,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
void BpApplicationManagerObserver::on_session_died(int id,
int stage_hint,
const String8& desktop_file_hint)
{
Parcel in, out;
in.writeInt32(id);
in.writeInt32(stage_hint);
in.writeString8(desktop_file_hint);
remote()->transact(
ON_SESSION_DIED_NOTIFICATION,
in,
&out,
android::IBinder::FLAG_ONEWAY);
}
BnApplicationManager::BnApplicationManager()
{
}
BnApplicationManager::~BnApplicationManager()
{
}
status_t BnApplicationManager::onTransact(uint32_t code,
const Parcel& data,
Parcel* reply,
uint32_t flags)
{
switch(code)
{
case START_A_NEW_SESSION_COMMAND:
{
int32_t session_type = data.readInt32();
int32_t stage_hint = data.readInt32();
String8 app_name = data.readString8();
String8 desktop_file = data.readString8();
sp binder = data.readStrongBinder();
sp session(new BpApplicationManagerSession(binder));
int fd = data.readFileDescriptor();
uint32_t remote_pid = data.readInt32();
start_a_new_session(session_type, stage_hint, app_name, desktop_file, session, fd, remote_pid);
}
break;
case REGISTER_A_SURFACE_COMMAND:
{
String8 title = data.readString8();
sp binder = data.readStrongBinder();
sp session(new BpApplicationManagerSession(binder));
int32_t surface_role = data.readInt32();
int32_t surface_token = data.readInt32();
int fd = data.readFileDescriptor();
register_a_surface(title, session, surface_role, surface_token, fd);
}
break;
case GET_SESSION_PID_COMMAND:
{
sp binder = data.readStrongBinder();
sp session(new BpApplicationManagerSession(binder));
int pid = get_session_pid(session);
reply->writeInt32(pid);
}
break;
case REQUEST_FULLSCREEN_COMMAND:
{
sp binder = data.readStrongBinder();
sp session(new BpApplicationManagerSession(binder));
request_fullscreen(session);
}
break;
case REGISTER_AN_OBSERVER_COMMAND:
{
sp binder = data.readStrongBinder();
sp observer(new BpApplicationManagerObserver(binder));
register_an_observer(observer);
break;
}
case REGISTER_TASK_CONTROLLER_COMMAND:
{
sp binder = data.readStrongBinder();
sp controller(new BpAMTaskController(binder));
register_task_controller(controller);
break;
}
case REQUEST_UPDATE_FOR_SESSION_COMMAND:
{
sp binder = data.readStrongBinder();
sp session(new BpApplicationManagerSession(binder));
request_update_for_session(session);
break;
}
case UNFOCUS_RUNNING_SESSIONS_COMMAND:
{
unfocus_running_sessions();
break;
}
case FOCUS_RUNNING_SESSION_WITH_ID_COMMAND:
{
int32_t id = data.readInt32();
focus_running_session_with_id(id);
break;
}
case QUERY_SNAPSHOT_LAYER_FOR_SESSION_WITH_ID_COMMAND:
{
int32_t id = data.readInt32();
int32_t layer = query_snapshot_layer_for_session_with_id(id);
reply->writeInt32(layer);
break;
}
case QUERY_SURFACE_PROPERTIES_FOR_SESSION_ID_COMMAND:
{
int32_t id = data.readInt32();
IApplicationManagerSession::SurfaceProperties props =
query_surface_properties_for_session_id(id);
reply->writeInt32(props.layer);
reply->writeInt32(props.left);
reply->writeInt32(props.top);
reply->writeInt32(props.right);
reply->writeInt32(props.bottom);
break;
}
case SWITCH_TO_WELL_KNOWN_APPLICATION_COMMAND:
{
int32_t app = data.readInt32();
switch_to_well_known_application(app);
break;
}
case SET_SURFACE_TRAP_COMMAND:
{
int32_t x = data.readInt32();
int32_t y = data.readInt32();
int32_t width = data.readInt32();
int32_t height = data.readInt32();
int32_t handle = set_surface_trap(x, y, width, height);
reply->writeInt32(handle);
break;
}
case UNSET_SURFACE_TRAP_COMMAND:
{
int32_t handle = data.readInt32();
unset_surface_trap(handle);
break;
}
case REPORT_OSK_VISIBLE_COMMAND:
{
int32_t x = data.readInt32();
int32_t y = data.readInt32();
int32_t width = data.readInt32();
int32_t height = data.readInt32();
report_osk_visible(x, y, width, height);
break;
}
case REPORT_OSK_INVISIBLE_COMMAND:
{
report_osk_invisible();
break;
}
case REPORT_NOTIFICATION_VISIBLE_COMMAND:
{
report_notification_visible();
break;
}
case REPORT_NOTIFICATION_INVISIBLE_COMMAND:
{
report_notification_invisible();
break;
}
}
return NO_ERROR;
}
BpApplicationManager::BpApplicationManager(const sp& impl)
: BpInterface(impl)
{
}
BpApplicationManager::~BpApplicationManager()
{
}
void BpApplicationManager::start_a_new_session(
int32_t session_type,
int32_t stage_hint,
const String8& app_name,
const String8& desktop_file,
const sp& session,
int fd,
uint32_t remote_pid)
{
//printf("%s \n", __PRETTY_FUNCTION__);
Parcel in, out;
in.pushAllowFds(true);
in.writeInt32(session_type);
in.writeInt32(stage_hint);
in.writeString8(app_name);
in.writeString8(desktop_file);
in.writeStrongBinder(session->asBinder());
in.writeFileDescriptor(fd);
in.writeInt32(remote_pid);
remote()->transact(START_A_NEW_SESSION_COMMAND,
in,
&out);
}
void BpApplicationManager::register_a_surface(
const String8& title,
const sp& session,
int32_t surface_role,
int32_t token,
int fd)
{
//printf("%s \n", __PRETTY_FUNCTION__);
Parcel in, out;
in.pushAllowFds(true);
in.writeString8(title);
in.writeStrongBinder(session->asBinder());
in.writeInt32(surface_role);
in.writeInt32(token);
in.writeFileDescriptor(fd);
remote()->transact(REGISTER_A_SURFACE_COMMAND,
in,
&out);
}
int BpApplicationManager::get_session_pid(
const sp& session)
{
Parcel in, out;
in.writeStrongBinder(session->asBinder());
remote()->transact(GET_SESSION_PID_COMMAND,
in,
&out);
int32_t pid = out.readInt32();
return pid;
}
void BpApplicationManager::request_fullscreen(
const sp& session)
{
//printf("%s \n", __PRETTY_FUNCTION__);
Parcel in, out;
in.writeStrongBinder(session->asBinder());
remote()->transact(REQUEST_FULLSCREEN_COMMAND,
in,
&out);
}
void BpApplicationManager::register_task_controller(const sp& controller)
{
Parcel in, out;
in.writeStrongBinder(controller->asBinder());
remote()->transact(REGISTER_TASK_CONTROLLER_COMMAND,
in,
&out);
}
void BpApplicationManager::register_an_observer(const sp& observer)
{
Parcel in, out;
in.writeStrongBinder(observer->asBinder());
remote()->transact(REGISTER_AN_OBSERVER_COMMAND,
in,
&out);
}
void BpApplicationManager::request_update_for_session(const sp& session)
{
Parcel in, out;
in.writeStrongBinder(session->asBinder());
remote()->transact(REQUEST_UPDATE_FOR_SESSION_COMMAND,
in,
&out);
}
void BpApplicationManager::unfocus_running_sessions()
{
Parcel in, out;
remote()->transact(UNFOCUS_RUNNING_SESSIONS_COMMAND,
in,
&out);
}
void BpApplicationManager::focus_running_session_with_id(int id)
{
Parcel in, out;
in.writeInt32(id);
remote()->transact(FOCUS_RUNNING_SESSION_WITH_ID_COMMAND,
in,
&out);
}
int32_t BpApplicationManager::query_snapshot_layer_for_session_with_id(int id)
{
Parcel in, out;
in.writeInt32(id);
remote()->transact(QUERY_SNAPSHOT_LAYER_FOR_SESSION_WITH_ID_COMMAND,
in,
&out);
int32_t layer = out.readInt32();
return layer;
}
IApplicationManagerSession::SurfaceProperties BpApplicationManager::query_surface_properties_for_session_id(int id)
{
Parcel in, out;
in.writeInt32(id);
remote()->transact(QUERY_SURFACE_PROPERTIES_FOR_SESSION_ID_COMMAND,
in,
&out);
IApplicationManagerSession::SurfaceProperties props;
props.layer = out.readInt32();
props.left = out.readInt32();
props.top = out.readInt32();
props.right = out.readInt32();
props.bottom = out.readInt32();
return props;
}
void BpApplicationManager::switch_to_well_known_application(int32_t app)
{
Parcel in, out;
in.writeInt32(app);
remote()->transact(SWITCH_TO_WELL_KNOWN_APPLICATION_COMMAND,
in,
&out);
}
int32_t BpApplicationManager::set_surface_trap(int32_t x, int32_t y, int32_t width, int32_t height)
{
Parcel in, out;
in.writeInt32(x);
in.writeInt32(y);
in.writeInt32(width);
in.writeInt32(height);
remote()->transact(SET_SURFACE_TRAP_COMMAND,
in,
&out);
int32_t handle = out.readInt32();
return handle;
}
void BpApplicationManager::unset_surface_trap(int32_t handle)
{
Parcel in, out;
in.writeInt32(handle);
remote()->transact(UNSET_SURFACE_TRAP_COMMAND,
in,
&out);
}
void BpApplicationManager::report_osk_visible(int32_t x, int32_t y, int32_t width, int32_t height)
{
Parcel in, out;
in.writeInt32(x);
in.writeInt32(y);
in.writeInt32(width);
in.writeInt32(height);
remote()->transact(REPORT_OSK_VISIBLE_COMMAND,
in,
&out);
}
void BpApplicationManager::report_osk_invisible()
{
Parcel in, out;
remote()->transact(REPORT_OSK_INVISIBLE_COMMAND,
in,
&out);
}
void BpApplicationManager::report_notification_visible()
{
Parcel in, out;
remote()->transact(REPORT_NOTIFICATION_VISIBLE_COMMAND,
in,
&out);
}
void BpApplicationManager::report_notification_invisible()
{
Parcel in, out;
remote()->transact(REPORT_NOTIFICATION_INVISIBLE_COMMAND,
in,
&out);
}
}
platform-api-0.20+14.04.20140411/android/hybris/test_gps_api.cpp 0000644 0000153 0177776 00000014324 12322054725 024533 0 ustar pbuser nogroup 0000000 0000000 /*
* Copyright © 2013 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Daniel d'Andrada
*/
#include
#include
#include
#include
#include
#include
class GPSTest
{
public:
GPSTest();
~GPSTest();
bool init_and_start();
bool stop();
void inject_time();
UbuntuGps ubuntu_gps;
};
void gps_location_cb(UbuntuGpsLocation* location, void* context)
{
printf("gps_location_cb() called.\n");
}
void gps_status_cb(uint16_t status, void* context)
{
switch(status)
{
case UBUNTU_GPS_STATUS_NONE:
printf("status: None\n");
break;
case UBUNTU_GPS_STATUS_SESSION_BEGIN:
printf("status: Session Begin\n");
break;
case UBUNTU_GPS_STATUS_SESSION_END:
printf("status: Session End\n");
break;
case UBUNTU_GPS_STATUS_ENGINE_ON:
printf("status: Engine On\n");
break;
case UBUNTU_GPS_STATUS_ENGINE_OFF:
printf("status: Engine Off\n");
default:
break;
};
}
void gps_sb_status_cb(UbuntuGpsSvStatus* sv_info, void* context)
{
printf("gps_sb_status_cb() called, listing %d space vehicles\n", sv_info->num_svs);
}
void gps_nmea_cb(int64_t timestamp, const char* nmea, int length, void* context)
{
char str[length+1];
memcpy(str, nmea, length);
str[length] = 0;
printf("gps_nmea_cb() - %s\n", str);
}
void gps_set_cabapilities_cb(uint32_t capabilities, void* context)
{
printf("gps_set_cabapilities_cb() -");
if (capabilities & UBUNTU_GPS_CAPABILITY_SCHEDULING)
printf(" scheduling");
if (capabilities & UBUNTU_GPS_CAPABILITY_MSB)
printf(" MSB");
if (capabilities & UBUNTU_GPS_CAPABILITY_MSA)
printf(" MSA");
if (capabilities & UBUNTU_GPS_CAPABILITY_SINGLE_SHOT)
printf(" 'single shot'");
if (capabilities & UBUNTU_GPS_CAPABILITY_ON_DEMAND_TIME)
printf(" 'on demand time'");
printf("\n");
}
void gps_request_utc_time_cb(void* context)
{
printf("gps_request_utc_time_cb() called.\n");
((GPSTest*)context)->inject_time();
}
void gps_xtra_download_request_cb(void* context)
{
printf("gps_xtra_download_request_cb() called.\n");
}
void agps_status_cb(UbuntuAgpsStatus* status, void* context)
{
printf("agps status -");
if (status->type == UBUNTU_AGPS_TYPE_SUPL)
printf(" SUPL");
else
printf(" C2K");
switch (status->status)
{
case UBUNTU_GPS_REQUEST_AGPS_DATA_CONN:
printf(", request AGPS data connection");
break;
case UBUNTU_GPS_RELEASE_AGPS_DATA_CONN:
printf(", release AGPS data connection");
break;
case UBUNTU_GPS_AGPS_DATA_CONNECTED:
printf(", request AGPS data connected");
break;
case UBUNTU_GPS_AGPS_DATA_CONN_DONE:
printf(", AGPS data connection done");
break;
default:
case UBUNTU_GPS_AGPS_DATA_CONN_FAILED:
printf(", AGPS data connection failed");
break;
}
printf(" ipaddr=%u\n", status->ipaddr);
}
void gps_notify_cb(UbuntuGpsNiNotification *notification, void* context)
{
printf("gps_notify_cb() called.\n");
}
void agps_ril_request_set_id_cb(uint32_t flags, void* context)
{
printf("agps_ril_request_set_id_cb() called.\n");
}
void agps_ril_request_refloc_cb(uint32_t flags, void* context)
{
printf("agps_ril_request_refloc_cb() called.\n");
}
GPSTest::GPSTest()
: ubuntu_gps(NULL)
{
}
GPSTest::~GPSTest()
{
if (ubuntu_gps)
ubuntu_gps_delete(ubuntu_gps);
}
void GPSTest::inject_time()
{
// A real implementation would inject time from some NTP server.
time_t t = time(0);
int64_t time_millis = (int64_t)t * (int64_t)1000;
ubuntu_gps_inject_time(ubuntu_gps,
time_millis /*NTP time would go here*/,
time_millis /*internal time when that NTP time was taken*/,
10 /* possible deviation, in milliseconds*/);
}
bool GPSTest::init_and_start()
{
UbuntuGpsParams gps_params;
gps_params.location_cb = gps_location_cb;
gps_params.status_cb = gps_status_cb;
gps_params.sv_status_cb = gps_sb_status_cb;
gps_params.nmea_cb = gps_nmea_cb;
gps_params.set_capabilities_cb = gps_set_cabapilities_cb;
gps_params.request_utc_time_cb = gps_request_utc_time_cb;
gps_params.xtra_download_request_cb = gps_xtra_download_request_cb;
gps_params.agps_status_cb = agps_status_cb;
gps_params.gps_ni_notify_cb = gps_notify_cb;
gps_params.request_setid_cb = agps_ril_request_set_id_cb;
gps_params.request_refloc_cb = agps_ril_request_refloc_cb;
gps_params.context = this;
UbuntuGps ubuntu_gps = ubuntu_gps_new(&gps_params);
if (!ubuntu_gps)
{
printf("GPS creation failed!\n");
return false;
}
bool ok = ubuntu_gps_start(ubuntu_gps);
if (!ok)
{
printf("GPS start up failed!\n");
return false;
}
return true;
}
bool GPSTest::stop()
{
bool ok = ubuntu_gps_stop(ubuntu_gps);
if (!ok)
printf("failed when stopping GPS!\n");
return ok;
}
void wait_for_sigint()
{
sigset_t signals;
sigemptyset(&signals);
sigaddset(&signals, SIGINT);
int sig;
int result = sigwait(&signals, &sig);
if (result != 0)
printf("sigwait failed!\n");
}
int main(int argc, char** argv)
{
int return_value = 0;
GPSTest test;
if (!test.init_and_start())
return 1;
printf("GPS initialized and started. Now waiting for callbacks or SIGINT (to quit).\n");
wait_for_sigint();
printf("Exiting...\n");
if (!test.stop())
return 1;
printf("GPS stopped.\n");
return 0;
}
platform-api-0.20+14.04.20140411/android/hybris/test.cpp 0000644 0000153 0177776 00000022563 12322054725 023035 0 ustar pbuser nogroup 0000000 0000000 /*
* Copyright © 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Authored by: Thomas Voß
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace
{
struct InputListener : public ubuntu::application::ui::input::Listener
{
void on_new_event(const Event& /*ev*/)
{
printf("%s \n", __PRETTY_FUNCTION__);
}
};
struct View
{
static const char* vertex_shader();
static const char* fragment_shader();
static GLuint load_shader(GLenum shaderType, const char* pSource);
static GLuint create_program(const char* pVertexSource, const char* pFragmentSource);
static const GLfloat* triangle()
{
static const GLfloat result[] =
{
-0.125f, -0.125f, 0.0f, 0.5f,
0.0f, 0.125f, 0.0f, 0.5f,
0.125f, -0.125f, 0.0f, 0.5f
};
return result;
}
static const GLfloat* color_triangle()
{
static const GLfloat result[] =
{
0.0f, 0.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f, 0.0f
};
return result;
}
View(const ubuntu::application::ui::Surface::Ptr& surface);
void render();
void step();
ubuntu::application::ui::Surface::Ptr surface;
EGLDisplay egl_display;
EGLSurface egl_surface;
EGLConfig egl_config;
EGLContext egl_context;
GLfloat rotation_angle;
GLuint gProgram;
GLuint gvPositionHandle, gvColorHandle;
GLuint rotation_uniform;
GLint num_vertex;
const GLfloat * vertex_data;
const GLfloat * color_data;
};
}
int main(int argc, char** argv)
{
ubuntu::application::ui::init(argc, argv);
ubuntu::application::ui::Setup::instance();
::SessionCredentials sc;
memset(&sc, 0, sizeof(sc));
snprintf(sc.application_name, sizeof(sc.application_name), "TestTestTest");
ubuntu::application::ui::SessionCredentials creds(&sc);
ubuntu::application::ui::Session::Ptr session =
ubuntu::ui::SessionService::instance()->start_a_new_session(creds);
ubuntu::application::ui::PhysicalDisplayInfo::Ptr p =
session->physical_display_info(ubuntu::application::ui::primary_physical_display);
printf("Resolution: (%dx%d)\n", p->horizontal_resolution(), p->vertical_resolution());
ubuntu::application::ui::SurfaceProperties props =
{
"MainActorSurface",
500,
500,
ubuntu::application::ui::main_actor_role
};
ubuntu::application::ui::Surface::Ptr surface =
session->create_surface(
props,
ubuntu::application::ui::input::Listener::Ptr(new InputListener()));
surface->set_alpha(0.5f);
View view(surface);
int x = 0;
while (true)
{
view.render();
view.step();
x++;
surface->move_to(x % p->horizontal_resolution(), 0);
}
}
namespace
{
const char* View::vertex_shader()
{
static const char shader[] =
"attribute vec4 vPosition;\n"
"attribute vec4 vColor;\n"
"uniform float angle;\n"
"varying vec4 colorinfo;\n"
"void main() {\n"
" mat3 rot_z = mat3( vec3( cos(angle), sin(angle), 0.0),\n"
" vec3(-sin(angle), cos(angle), 0.0),\n"
" vec3( 0.0, 0.0, 1.0));\n"
" gl_Position = vec4(rot_z * vPosition.xyz, 1.0);\n"
" colorinfo = vColor;\n"
"}\n";
return shader;
}
const char* View::fragment_shader()
{
static const char shader[] =
"precision mediump float;\n"
"varying vec4 colorinfo;\n"
"void main() {\n"
" gl_FragColor = colorinfo;\n"
"}\n";
return shader;
}
GLuint View::load_shader(GLenum shaderType, const char* pSource)
{
GLuint shader = glCreateShader(shaderType);
if (shader)
{
glShaderSource(shader, 1, &pSource, NULL);
glCompileShader(shader);
GLint compiled = 0;
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
if (!compiled)
{
GLint infoLen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
if (infoLen)
{
char* buf = (char*) malloc(infoLen);
if (buf)
{
glGetShaderInfoLog(shader, infoLen, NULL, buf);
fprintf(stderr, "Could not compile shader %d:\n%s\n",
shaderType, buf);
free(buf);
}
glDeleteShader(shader);
shader = 0;
}
}
}
else
{
printf("Error, during shader creation: %i\n", glGetError());
}
return shader;
}
GLuint View::create_program(const char* pVertexSource, const char* pFragmentSource)
{
GLuint vertexShader = load_shader(GL_VERTEX_SHADER, pVertexSource);
if (!vertexShader)
{
printf("vertex shader not compiled\n");
return 0;
}
GLuint pixelShader = load_shader(GL_FRAGMENT_SHADER, pFragmentSource);
if (!pixelShader)
{
printf("frag shader not compiled\n");
return 0;
}
GLuint program = glCreateProgram();
if (program)
{
glAttachShader(program, vertexShader);
glAttachShader(program, pixelShader);
glLinkProgram(program);
GLint linkStatus = GL_FALSE;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus != GL_TRUE)
{
GLint bufLength = 0;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
if (bufLength)
{
char* buf = (char*) malloc(bufLength);
if (buf)
{
glGetProgramInfoLog(program, bufLength, NULL, buf);
fprintf(stderr, "Could not link program:\n%s\n", buf);
free(buf);
}
}
glDeleteProgram(program);
program = 0;
}
}
return program;
}
View::View(const ubuntu::application::ui::Surface::Ptr& surface)
: surface(surface),
rotation_angle(0.f),
num_vertex(3)
{
// assert(eglBindAPI(EGL_OPENGL_ES_API) == EGL_TRUE);
egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
assert(egl_display != EGL_NO_DISPLAY);
EGLint major, minor;
if (EGL_FALSE == eglInitialize(egl_display, &major, &minor))
{
printf("egl error: problem initializing.\n");
exit(1);
}
EGLint attribs[] =
{
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_NONE
};
EGLint n;
if (EGL_FALSE == eglChooseConfig(
egl_display,
attribs,
&egl_config,
1,
&n))
{
printf("egl error: Cannot choose configuration.\n");
}
EGLint context_attribs[] =
{
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
egl_context = eglCreateContext(
egl_display,
egl_config,
EGL_NO_CONTEXT,
context_attribs);
assert(EGL_NO_CONTEXT != eglContext);
EGLNativeWindowType nativeWindow = surface->to_native_window_type();
egl_surface = eglCreateWindowSurface(egl_display, egl_config, nativeWindow, NULL);
eglMakeCurrent(
egl_display,
egl_surface,
egl_surface,
egl_context);
vertex_data = triangle();
color_data = color_triangle();
gProgram = create_program(vertex_shader(), fragment_shader());
if (!gProgram)
{
printf("error making program\n");
return;
}
gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
gvColorHandle = glGetAttribLocation(gProgram, "vColor");
rotation_uniform = glGetUniformLocation(gProgram, "angle");
return;
}
void View::render()
{
glUseProgram(gProgram);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glUniform1fv(rotation_uniform, 1, &rotation_angle);
glVertexAttribPointer(
gvColorHandle,
num_vertex,
GL_FLOAT,
GL_FALSE,
sizeof(GLfloat)*4, color_data);
glVertexAttribPointer(
gvPositionHandle,
num_vertex,
GL_FLOAT,
GL_FALSE,
0,
vertex_data);
glEnableVertexAttribArray(gvPositionHandle);
glEnableVertexAttribArray(gvColorHandle);
glDrawArrays(GL_TRIANGLE_STRIP, 0, num_vertex);
glDisableVertexAttribArray(gvPositionHandle);
glDisableVertexAttribArray(gvColorHandle);
eglSwapBuffers(egl_display, egl_surface);
}
void View::step()
{
rotation_angle += 0.01;
}
}
platform-api-0.20+14.04.20140411/android/hybris/default_application_manager.cpp 0000644 0000153 0177776 00000122361 12322054725 027554 0 ustar pbuser nogroup 0000000 0000000 /*
* Copyright © 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* Authored by: Thomas Voß
*/
#undef LOG_TAG
#define LOG_TAG "ubuntu::detail::ApplicationManager"
#include "default_application_manager.h"
#include "default_application_manager_input_setup.h"
#include "default_application_session.h"
#include "default_shell.h"
#include
#include
#include
#include
#include
#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
#include
#else
#include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace ubuntu { namespace detail
{
template
const T& min(const T& lhs, const U& rhs)
{
return lhs < rhs ? lhs : rhs;
}
/* TODO: Currently we need to map local pids to the ones of the
* container where Ubuntu is running as sessions need to be
* referenced to observers in terms of the said namespace.
*/
pid_t pid_to_vpid(int pid)
{
ALOGI("%s(%d)", __PRETTY_FUNCTION__, pid);
if (pid <= 0)
return -1;
char proc_name[128], buf[1024];
char *rpid;
char key[] = "Vpid:";
sprintf(proc_name, "/proc/%d/status", pid);
int fd;
fd = open(proc_name, O_RDONLY);
if (fd < 0)
{
ALOGI("%s(): Cannot find %s\n", __PRETTY_FUNCTION__, proc_name);
return -1;
}
memset(buf, '\0', sizeof(buf));
read(fd, buf, sizeof(buf));
rpid = strstr(buf, key);
close(fd);
if (rpid == NULL)
{
ALOGI("%s(): Vpid not supported\n", __PRETTY_FUNCTION__);
return pid;
}
return atoi(rpid+sizeof(key));
}
bool is_session_allowed_to_run_in_background(
const android::sp& session)
{
ALOGI("%s: %s", __PRETTY_FUNCTION__, session->desktop_file.string());
static const android::String8 phone_app_desktop_file("/usr/share/applications/phone-app.desktop");
static const android::String8 music_app_desktop_file("/usr/share/applications/music-app.desktop");
if (session->desktop_file == phone_app_desktop_file ||
session->desktop_file == music_app_desktop_file)
{
return true;
}
return false;
}
bool write_proc_file(pid_t pid, const char* filename, const char* value)
{
char proc_name[128];
sprintf(proc_name, "/proc/%d/%s", pid, filename);
int file;
if (access(proc_name, F_OK) == 0)
{
file = open(proc_name, O_WRONLY);
write(file, value, sizeof(value));
close(file);
return true;
} else
return false;
}
void update_oom_values(const android::sp& session)
{
if (session->session_type == ubuntu::application::ui::system_session_type)
{
if (!write_proc_file(session->pid, "oom_score_adj", "-940"))
write_proc_file(session->pid, "oom_adj", "-16");
return;
}
if (session->running_state == ubuntu::application::ui::process_suspended)
{
if (!write_proc_file(session->pid, "oom_score_adj", "1000"))
write_proc_file(session->pid, "oom_adj", "15");
} else
{
if (!write_proc_file(session->pid, "oom_score_adj", "0"))
write_proc_file(session->pid, "oom_adj", "0");
}
}
template
int ApplicationManager::ShellInputSetup::Window::looper_callback(int receiveFd, int events, void* ctxt)
{
// ALOGI("%s", __PRETTY_FUNCTION__);
bool result = true;
ApplicationManager::ShellInputSetup::Window* window = static_cast*>(ctxt);
//window->input_consumer.receiveDispatchSignal();
uint32_t seq;
android::InputEvent* ev;
static const bool consume_batches = true;
static const nsecs_t frame_time = -1;
switch(window->input_consumer.consume(&window->event_factory, consume_batches, frame_time, &seq, &ev))
{
case android::OK:
result = true;
//printf("We have a client side event for process %d. \n", getpid());
window->input_consumer.sendFinishedSignal(seq, result);
break;
case android::INVALID_OPERATION:
result = true;
break;
case android::NO_MEMORY:
result = true;
break;
}
return result ? 1 : 0;
}
template
ApplicationManager::ShellInputSetup::Window::Window(
ApplicationManager::ShellInputSetup* parent,
int _x,
int _y,
int _w,
int _h) : parent(parent),
input_consumer(client_channel)
{
auto window = new android::InputSetup::DummyApplicationWindow(
parent->shell_application,
_x,
_y,
_w,
_h);
android::InputChannel::openInputChannelPair(
android::String8("DummyShellInputChannel"),
server_channel,
client_channel);
window->input_channel = server_channel;
input_window = window;
parent->input_manager->getDispatcher()->registerInputChannel(
window->input_channel,
input_window,
false);
input_consumer = android::InputConsumer(client_channel);
// input_consumer.initialize();
parent->looper->addFd(client_channel->getFd(), //client_channel->getReceivePipeFd(),
0,
ALOOPER_EVENT_INPUT,
looper_callback,
this);
}
ApplicationManager::ShellInputSetup::DisplayInfo::DisplayInfo()
{
auto display = android::SurfaceComposerClient::getBuiltInDisplay(
android::ISurfaceComposer::eDisplayIdMain);
android::SurfaceComposerClient::getDisplayInfo(
display,
&info);
}
ApplicationManager::ShellInputSetup::ShellInputSetup(const android::sp& input_manager)
: shell_has_focus(true),
input_manager(input_manager),
shell_application(new android::InputSetup::DummyApplication()),
looper(new android::Looper(true)),
event_loop(looper),
event_trap_window(this, 0, 0, display_info.info.w, display_info.info.h),
osk_window(this),
notifications_window(this)
{
event_loop.run();
}
ApplicationManager::InputFilter::InputFilter(ApplicationManager* manager) : manager(manager)
{
}
bool ApplicationManager::InputFilter::filter_event(const android::InputEvent* event)
{
bool result = true;
switch (event->getType())
{
case AINPUT_EVENT_TYPE_KEY:
result = handle_key_event(static_cast(event));
break;
}
return result;
}
bool ApplicationManager::InputFilter::handle_key_event(const android::KeyEvent* event)
{
bool result = true;
return result;
}
ApplicationManager::LockingIterator::LockingIterator(
ApplicationManager* manager,
size_t index) : manager(manager),
it(index)
{
}
void ApplicationManager::LockingIterator::advance()
{
it += 1;
}
bool ApplicationManager::LockingIterator::is_valid() const
{
return it < manager->apps.size();
}
void ApplicationManager::LockingIterator::make_current()
{
//printf("%s \n", __PRETTY_FUNCTION__);
}
const android::sp& ApplicationManager::LockingIterator::operator*()
{
return manager->apps.valueFor(manager->apps_as_added[it]);
}
ApplicationManager::LockingIterator::~LockingIterator()
{
manager->unlock();
}
ApplicationManager::ApplicationManager() : input_filter(new InputFilter(this)),
input_setup(new android::InputSetup(input_filter)),
is_osk_visible(false),
are_notifications_visible(false),
app_manager_task_controller(NULL),
focused_application(0),
side_stage_application(0),
main_stage_application(0)
{
shell_input_setup = new ShellInputSetup(input_setup->input_manager);
input_setup->input_manager->getDispatcher()->setFocusedApplication(
shell_input_setup->shell_application);
android::Vector< android::sp > input_windows;
input_windows.push(shell_input_setup->event_trap_window.input_window);
input_setup->input_manager->getDispatcher()->setInputWindows(
input_windows);
input_setup->start();
}
void ApplicationManager::update_app_lists()
{
int idx;
for (idx = apps_as_added.size()-1; idx >= 0; idx--)
{
const android::sp& session =
apps.valueFor(apps_as_added[idx]);
if (session->session_type == ubuntu::application::ui::system_session_type)
continue;
if (session->stage_hint == ubuntu::application::ui::side_stage)
{
side_stage_application = idx;
break;
}
}
if (idx < 0)
side_stage_application = 0;
for (idx = apps_as_added.size()-1; idx >= 0; idx--)
{
const android::sp& session =
apps.valueFor(apps_as_added[idx]);
if (session->session_type == ubuntu::application::ui::system_session_type)
continue;
if (session->stage_hint == ubuntu::application::ui::main_stage)
{
main_stage_application = idx;
break;
}
}
if (idx < 0)
main_stage_application = 0;
}
// From DeathRecipient
void ApplicationManager::binderDied(const android::wp& who)
{
android::Mutex::Autolock al(guard);
android::sp sp = who.promote();
ALOGI("%s():%d\n", __PRETTY_FUNCTION__, __LINE__);
const android::sp& dead_session = apps.valueFor(sp);
ALOGI("%s():%d -- remote_pid=%d desktop_file=%s\n", __PRETTY_FUNCTION__, __LINE__,
dead_session->remote_pid,
dead_session->desktop_file.string());
notify_observers_about_session_died(dead_session->remote_pid,
dead_session->stage_hint,
dead_session->desktop_file);
ALOGI("%s():%d\n", __PRETTY_FUNCTION__, __LINE__);
size_t i = 0;
for(i = 0; i < apps_as_added.size(); i++)
if (apps_as_added[i] == sp)
break;
ALOGI("%s():%d\n", __PRETTY_FUNCTION__, __LINE__);
size_t next_focused_app = 0;
next_focused_app = apps_as_added.removeAt(i);
ALOGI("%s():%d\n", __PRETTY_FUNCTION__, __LINE__);
next_focused_app = main_stage_application;
update_app_lists();
ALOGI("%s():%d\n", __PRETTY_FUNCTION__, __LINE__);
if (dead_session->stage_hint == ubuntu::application::ui::side_stage)
next_focused_app = side_stage_application ? side_stage_application : next_focused_app;
ALOGI("%s():%d\n", __PRETTY_FUNCTION__, __LINE__);
if (dead_session->stage_hint == ubuntu::application::ui::main_stage)
next_focused_app = main_stage_application;
ALOGI("%s():%d\n", __PRETTY_FUNCTION__, __LINE__);
if (i && i == focused_application &&
shell_input_setup->shell_has_focus == false)
{
switch_focused_application_locked(next_focused_app);
}
else if(focused_application > i)
focused_application--;
if (i == 0)
{
shell_input_setup->trap_windows.clear();
shell_input_setup->shell_has_focus = true;
}
ALOGI("%s():%d\n", __PRETTY_FUNCTION__, __LINE__);
apps.removeItem(sp);
ALOGI("%s():%d\n", __PRETTY_FUNCTION__, __LINE__);
}
void ApplicationManager::lock()
{
guard.lock();
}
void ApplicationManager::unlock()
{
guard.unlock();
}
android::sp ApplicationManager::iterator()
{
lock();
android::sp it(
new ApplicationManager::LockingIterator(this, 0));
return it;
}
void ApplicationManager::session_set_state(const android::sp& as,
int32_t new_state)
{
ALOGI("%s():%d running->running", __PRETTY_FUNCTION__, __LINE__);
switch (new_state)
{
case ubuntu::application::ui::process_running:
{
if (as->running_state == ubuntu::application::ui::process_running)
{
ALOGI("%s():%d running->running", __PRETTY_FUNCTION__, __LINE__);
/* FIXME:
* Technically invalid, this transition currently is hit because
* of focus being requested on the session before its delagate call
*/
} else if (as->running_state == ubuntu::application::ui::process_destroyed)
{
ALOGI("%s():%d destroyed->running", __PRETTY_FUNCTION__, __LINE__);
/* TODO:
* Resume application with a null archive handler
*/
} else if (as->running_state == ubuntu::application::ui::process_stopped)
{
ALOGI("%s():%d stopped->running", __PRETTY_FUNCTION__, __LINE__);
/* TODO:
* Support starting the new process and wait for the
* session to be available to call its delegate
*/
return;
} else
{
/* suspended->running
* nothing to do, process image still in memory
*/
if (app_manager_task_controller != NULL)
app_manager_task_controller->continue_task(as->remote_pid);
else
kill(as->pid, SIGCONT);
}
as->running_state = ubuntu::application::ui::process_running;
as->on_application_resumed();
update_oom_values(as);
}
break;
case ubuntu::application::ui::process_suspended:
{
ALOGI("%s() state->suspended", __PRETTY_FUNCTION__);
/* TODO: create archive */
as->on_application_about_to_stop();
as->running_state = ubuntu::application::ui::process_suspended;
android::sp deferred_kill(new ubuntu::application::ProcessKiller(as, app_manager_task_controller));
deferred_kill->run();
update_oom_values(as);
}
break;
case ubuntu::application::ui::process_stopped:
{
ALOGI("%s() state->stopped", __PRETTY_FUNCTION__);
/* TODO:
* This transition occurs while SIGSTOP'd. Check we hold a valid archive
* and then destroy the process image. No need to signal via delegates.
*/
as->running_state = ubuntu::application::ui::process_stopped;
}
break;
case ubuntu::application::ui::process_destroyed:
{
ALOGI("%s() state->destroyed", __PRETTY_FUNCTION__);
/* TODO:
* Internal transition: Invalidate archive if any, destroy
* process image.
*/
as->running_state = ubuntu::application::ui::process_destroyed;
}
break;
}
}
void ApplicationManager::start_a_new_session(
int32_t session_type,
int32_t stage_hint,
const android::String8& app_name,
const android::String8& desktop_file,
const android::sp& session,
int fd,
uint32_t remote_pid)
{
android::Mutex::Autolock al(guard);
(void) session_type;
pid_t pid = android::IPCThreadState::self()->getCallingPid();
pid_t rpid;
if (!remote_pid)
{
ALOGI("%s() no remote_pid set from client, lookup in proc", __PRETTY_FUNCTION__);
rpid = pid_to_vpid(pid);
}
else
{
ALOGI("%s() remote_pid=%d", __PRETTY_FUNCTION__, remote_pid);
rpid = static_cast(remote_pid);
}
ALOGI("%s() starting new session pid=%d rpid=%d", __PRETTY_FUNCTION__, pid, rpid);
android::sp app_session(
new ubuntu::detail::ApplicationSession(
pid,
rpid,
session,
session_type,
stage_hint,
app_name,
desktop_file));
apps.add(session->asBinder(), app_session);
apps_as_added.push_back(session->asBinder());
session->asBinder()->linkToDeath(
android::sp(this));
switch(session_type)
{
case ubuntu::application::ui::user_session_type:
ALOGI("%s: Invoked for user_session_type \n", __PRETTY_FUNCTION__);
break;
case ubuntu::application::ui::system_session_type:
ALOGI("%s: Invoked for system_session_type \n", __PRETTY_FUNCTION__);
break;
}
notify_observers_about_session_born(app_session->remote_pid,
app_session->stage_hint,
app_session->desktop_file);
ALOGI("%s():%d session", __PRETTY_FUNCTION__, __LINE__);
}
void ApplicationManager::register_a_surface(
const android::String8& title,
const android::sp& session,
int32_t surface_role,
int32_t token,
int fd)
{
android::Mutex::Autolock al(guard);
android::sp input_channel(
new android::InputChannel(
title,
dup(fd)));
android::sp surface(
new ubuntu::detail::ApplicationSession::Surface(
apps.valueFor(session->asBinder()).get(),
input_channel,
surface_role,
token));
auto registered_session = apps.valueFor(session->asBinder());
ALOGI("Registering input channel as observer: %s",
registered_session->session_type == ubuntu::application::ui::system_session_type ? "true" : "false");
input_setup->input_manager->getDispatcher()->registerInputChannel(
surface->input_channel,
surface->make_input_window_handle(),
registered_session->session_type == ubuntu::application::ui::system_session_type);
registered_session->register_surface(surface);
if (registered_session->session_type == ubuntu::application::ui::system_session_type)
{
ALOGI("New surface for system session, adjusting layer now.");
switch(surface_role)
{
case ubuntu::application::ui::dash_actor_role:
registered_session->raise_surface_to_layer(token, default_dash_layer);
break;
case ubuntu::application::ui::indicator_actor_role:
registered_session->raise_surface_to_layer(token, default_indicator_layer);
break;
case ubuntu::application::ui::notifications_actor_role:
registered_session->raise_surface_to_layer(token, default_notifications_layer);
break;
case ubuntu::application::ui::greeter_actor_role:
registered_session->raise_surface_to_layer(token, default_greeter_layer);
break;
case ubuntu::application::ui::launcher_actor_role:
registered_session->raise_surface_to_layer(token, default_launcher_layer);
break;
case ubuntu::application::ui::on_screen_keyboard_actor_role:
registered_session->raise_surface_to_layer(token, default_osk_layer);
break;
case ubuntu::application::ui::shutdown_dialog_actor_role:
registered_session->raise_surface_to_layer(token, default_shutdown_dialog_layer);
break;
}
}
}
void ApplicationManager::request_fullscreen(const android::sp& session)
{
ALOGI("%s", __PRETTY_FUNCTION__);
android::Mutex::Autolock al(guard);
const android::sp& as =
apps.valueFor(session->asBinder());
notify_observers_about_session_requested_fullscreen(
as->remote_pid,
as->stage_hint,
as->desktop_file);
}
int ApplicationManager::get_session_pid(const android::sp& session)
{
ALOGI("%s", __PRETTY_FUNCTION__);
android::Mutex::Autolock al(guard);
if (apps.indexOfKey(session->asBinder()) == android::NAME_NOT_FOUND)
return 0;
const android::sp& as =
apps.valueFor(session->asBinder());
return as->remote_pid;
}
void ApplicationManager::request_update_for_session(const android::sp& session)
{
ALOGI("%s", __PRETTY_FUNCTION__);
android::Mutex::Autolock al(guard);
if (apps_as_added[focused_application] != session->asBinder())
return;
const android::sp& as =
apps.valueFor(apps_as_added[focused_application]);
if (as->session_type == ubuntu::application::ui::system_session_type)
{
input_setup->input_manager->getDispatcher()->setFocusedApplication(
shell_input_setup->shell_application);
android::Vector< android::sp > input_windows;
input_windows.push(shell_input_setup->event_trap_window.input_window);
input_setup->input_manager->getDispatcher()->setInputWindows(
input_windows);
} else
{
input_setup->input_manager->getDispatcher()->setFocusedApplication(
as->input_application_handle());
android::Vector< android::sp > input_windows;
if (is_osk_visible)
input_windows.push(shell_input_setup->osk_window.input_window);
if (are_notifications_visible)
input_windows.push(shell_input_setup->notifications_window.input_window);
if (!shell_input_setup->trap_windows.isEmpty())
{
int key = 0;
for (size_t i = 0; i < shell_input_setup->trap_windows.size(); i++)
{
key = shell_input_setup->trap_windows.keyAt(i);
input_windows.push(shell_input_setup->trap_windows.valueFor(key));
}
}
input_windows.appendVector(as->input_window_handles());
if (as->stage_hint == ubuntu::application::ui::side_stage)
{
const android::sp& main_session =
apps.valueFor(apps_as_added[main_stage_application]);
input_windows.appendVector(main_session->input_window_handles());
}
input_setup->input_manager->getDispatcher()->setInputWindows(
input_windows);
}
}
void ApplicationManager::register_task_controller(
const android::sp& controller)
{
ALOGI("%s() registering task controller", __PRETTY_FUNCTION__);
//TODO: Register the task controller to use it instead of sigkilling
android::Mutex::Autolock al(guard);
if (app_manager_task_controller != NULL)
return;
ALOGI("%s() done registering task controller", __PRETTY_FUNCTION__);
app_manager_task_controller = controller;
}
void ApplicationManager::register_an_observer(
const android::sp& observer)
{
android::Mutex::Autolock al(observer_guard);
app_manager_observers.push_back(observer);
{
android::Mutex::Autolock al(guard);
for(unsigned int i = 0; i < apps_as_added.size(); i++)
{
const android::sp& session =
apps.valueFor(apps_as_added[i]);
observer->on_session_born(session->remote_pid,
session->stage_hint,
session->desktop_file);
}
if (focused_application < apps_as_added.size())
{
const android::sp& session =
apps.valueFor(apps_as_added[focused_application]);
observer->on_session_focused(session->remote_pid,
session->stage_hint,
session->desktop_file);
}
}
}
void ApplicationManager::focus_running_session_with_id(int id)
{
android::Mutex::Autolock al(guard);
size_t idx = session_id_to_index(id);
if (idx < apps_as_added.size())
{
switch_focused_application_locked(idx);
}
}
void ApplicationManager::unfocus_running_sessions()
{
ALOGI("%s", __PRETTY_FUNCTION__);
android::Mutex::Autolock al(guard);
if (shell_input_setup->shell_has_focus)
return;
input_setup->input_manager->getDispatcher()->setFocusedApplication(
shell_input_setup->shell_application);
android::Vector< android::sp > input_windows;
input_windows.push(shell_input_setup->event_trap_window.input_window);
input_setup->input_manager->getDispatcher()->setInputWindows(
input_windows);
if (focused_application < apps.size())
{
const android::sp& session =
apps.valueFor(apps_as_added[focused_application]);
if (session->session_type != ubuntu::application::ui::system_session_type)
{
notify_observers_about_session_unfocused(session->remote_pid,
session->stage_hint,
session->desktop_file);
if (!is_session_allowed_to_run_in_background(session))
session_set_state(session, ubuntu::application::ui::process_suspended);
}
}
shell_input_setup->shell_has_focus = true;
}
int32_t ApplicationManager::query_snapshot_layer_for_session_with_id(int id)
{
size_t idx = session_id_to_index(id);
if (idx < apps_as_added.size())
{
return apps.valueFor(apps_as_added[idx])->layer();
}
return INT_MAX;
}
android::IApplicationManagerSession::SurfaceProperties ApplicationManager::query_surface_properties_for_session_id(int id)
{
android::Mutex::Autolock al(guard);
size_t idx = session_id_to_index(id);
android::IApplicationManagerSession::SurfaceProperties props;
int status;
if (idx < apps_as_added.size())
{
const android::sp& session =
apps.valueFor(apps_as_added[idx]);
if (session->running_state == ubuntu::application::ui::process_suspended)
{
kill(session->pid, SIGCONT);
props = session->query_properties();
kill(session->pid, SIGSTOP);
} else {
props = session->query_properties();
}
return props;
}
return android::IApplicationManagerSession::SurfaceProperties();
}
void ApplicationManager::switch_to_well_known_application(int32_t app)
{
notify_observers_about_session_requested(app);
}
int32_t ApplicationManager::set_surface_trap(int x, int y, int width, int height)
{
static int32_t key = 0;
ApplicationManager::ShellInputSetup::Window<0, 0, 2048, 2048>* w =
new ApplicationManager::ShellInputSetup::Window<0, 0, 2048, 2048>(shell_input_setup.get(), x, y, width, height);
key++;
shell_input_setup->trap_windows.add(key, w->input_window);
update_input_setup_locked();
return key;
}
void ApplicationManager::unset_surface_trap(int32_t handle)
{
shell_input_setup->trap_windows.removeItem(handle);
update_input_setup_locked();
}
void ApplicationManager::report_osk_visible(int32_t x, int32_t y, int32_t width, int32_t height)
{
ALOGI("%s(x=%d, y=%d, width=%d, height=%d)", __PRETTY_FUNCTION__, x, y, width, height);
shell_input_setup->osk_window.input_window->x = x;
shell_input_setup->osk_window.input_window->y = y;
shell_input_setup->osk_window.input_window->w = width;
shell_input_setup->osk_window.input_window->h = height;
android::Mutex::Autolock al(guard);
is_osk_visible = true;
update_input_setup_locked();
notify_observers_about_keyboard_geometry_changed(x, y, width, height);
}
void ApplicationManager::report_osk_invisible()
{
ALOGI("%s", __PRETTY_FUNCTION__);
android::Mutex::Autolock al(guard);
is_osk_visible = false;
update_input_setup_locked();
notify_observers_about_keyboard_geometry_changed(0, 0, 0, 0);
}
void ApplicationManager::report_notification_visible()
{
ALOGI("%s", __PRETTY_FUNCTION__);
android::Mutex::Autolock al(guard);
are_notifications_visible = true;
update_input_setup_locked();
}
void ApplicationManager::report_notification_invisible()
{
ALOGI("%s", __PRETTY_FUNCTION__);
android::Mutex::Autolock al(guard);
are_notifications_visible = false;
update_input_setup_locked();
}
void ApplicationManager::update_input_setup_locked()
{
if (focused_application >= apps.size())
return;
const android::sp& session =
apps.valueFor(apps_as_added[focused_application]);
if (shell_input_setup->shell_has_focus)
{
input_setup->input_manager->getDispatcher()->setFocusedApplication(
shell_input_setup->shell_application);
android::Vector< android::sp > input_windows;
input_windows.push(shell_input_setup->event_trap_window.input_window);
input_setup->input_manager->getDispatcher()->setInputWindows(
input_windows);
} else
{
ALOGI("Adjusting input setup to account for change in visibility of osk/notifications");
input_setup->input_manager->getDispatcher()->setFocusedApplication(
session->input_application_handle());
android::Vector< android::sp > input_windows;
if (is_osk_visible)
input_windows.push(shell_input_setup->osk_window.input_window);
if (are_notifications_visible)
input_windows.push(shell_input_setup->notifications_window.input_window);
if (!shell_input_setup->trap_windows.isEmpty())
{
int key = 0;
for (size_t i = 0; i < shell_input_setup->trap_windows.size(); i++)
{
key = shell_input_setup->trap_windows.keyAt(i);
input_windows.push(shell_input_setup->trap_windows.valueFor(key));
}
}
android::sp sb = apps_as_added[focused_application];
if (sb->isBinderAlive())
input_windows.appendVector(session->input_window_handles());
if (session->stage_hint == ubuntu::application::ui::side_stage)
{
const android::sp& main_session =
apps.valueFor(apps_as_added[main_stage_application]);
android::sp msb = apps_as_added[focused_application];
if (msb->isBinderAlive())
{
input_windows.appendVector(main_session->input_window_handles());
}
}
input_setup->input_manager->getDispatcher()->setInputWindows(
input_windows);
}
}
void ApplicationManager::switch_focused_application_locked(size_t index_of_next_focused_app)
{
static int focused_layer = 0;
static const int focused_layer_increment = 10;
if (apps.size() > 1 &&
focused_application < apps.size() &&
focused_application < apps_as_added.size() &&
focused_application != index_of_next_focused_app)
{
ALOGI("Lowering current application now for idx: %d \n", focused_application);
const android::sp& session =
apps.valueFor(apps_as_added[focused_application]);
const android::sp& next_session =
apps.valueFor(apps_as_added[index_of_next_focused_app]);
if (next_session->session_type == ubuntu::application::ui::system_session_type)
return;
if (session->session_type != ubuntu::application::ui::system_session_type)
{
// Stop the session
if (!is_session_allowed_to_run_in_background(session))
{
if ((session->stage_hint == ubuntu::application::ui::main_stage &&
next_session->stage_hint != ubuntu::application::ui::side_stage) ||
(session->stage_hint == ubuntu::application::ui::side_stage &&
next_session->stage_hint != ubuntu::application::ui::main_stage))
{
notify_observers_about_session_unfocused(session->remote_pid,
session->stage_hint,
session->desktop_file);
session_set_state(session, ubuntu::application::ui::process_suspended);
} else
{
if (session->stage_hint == ubuntu::application::ui::side_stage &&
next_session->stage_hint == ubuntu::application::ui::main_stage &&
main_stage_application < apps.size())
{
const android::sp& main_session =
apps.valueFor(apps_as_added[main_stage_application]);
if (main_session->session_type != ubuntu::application::ui::system_session_type)
session_set_state(main_session, ubuntu::application::ui::process_suspended);
}
}
}
}
}
focused_application = index_of_next_focused_app;
is_osk_visible = false;
notify_observers_about_keyboard_geometry_changed(0, 0, 0, 0);
if (focused_application < apps.size())
{
focused_layer += focused_layer_increment;
const android::sp& session =
apps.valueFor(apps_as_added[focused_application]);
ALOGI("Raising application now for idx: %d (stage_hint: %d)\n", focused_application, session->stage_hint);
if (session->session_type == ubuntu::application::ui::system_session_type)
{
ALOGI("\t system session - not raising it.");
return;
}
// Continue the session
if (!is_session_allowed_to_run_in_background(session))
session_set_state(session, ubuntu::application::ui::process_running);
if (session->stage_hint == ubuntu::application::ui::side_stage)
side_stage_application = focused_application;
else
main_stage_application = focused_application;
session->raise_application_surfaces_to_layer(focused_layer);
input_setup->input_manager->getDispatcher()->setFocusedApplication(
session->input_application_handle());
android::Vector< android::sp > input_windows;
if (are_notifications_visible)
input_windows.push(shell_input_setup->notifications_window.input_window);
if (!shell_input_setup->trap_windows.isEmpty())
{
int key = 0;
for (size_t i = 0; i < shell_input_setup->trap_windows.size(); i++)
{
key = shell_input_setup->trap_windows.keyAt(i);
input_windows.push(shell_input_setup->trap_windows.valueFor(key));
}
}
input_windows.appendVector(session->input_window_handles());
if (session->stage_hint == ubuntu::application::ui::side_stage)
{
if (main_stage_application)
{
const android::sp& main_session =
apps.valueFor(apps_as_added[main_stage_application]);
session_set_state(main_session, ubuntu::application::ui::process_running);
input_windows.appendVector(main_session->input_window_handles());
}
}
input_setup->input_manager->getDispatcher()->setInputWindows(
input_windows);
notify_observers_about_session_focused(session->remote_pid,
session->stage_hint,
session->desktop_file);
shell_input_setup->shell_has_focus = false;
}
}
void ApplicationManager::switch_focus_to_next_application_locked()
{
size_t new_idx = (focused_application + 1) % apps.size();
ALOGI("current: %d, next: %d \n", focused_application, new_idx);
switch_focused_application_locked(new_idx);
}
void ApplicationManager::kill_focused_application_locked()
{
if (focused_application < apps.size())
{
const android::sp& session =
apps.valueFor(apps_as_added[focused_application]);
kill(session->pid, SIGKILL);
}
}
size_t ApplicationManager::session_id_to_index(int id)
{
size_t idx = 0;
for(idx = 0; idx < apps_as_added.size(); idx++)
{
const android::sp& session =
apps.valueFor(apps_as_added[idx]);
if (session->remote_pid == id)
break;
}
return idx;
}
void ApplicationManager::notify_observers_about_session_requested(uint32_t app)
{
android::Mutex::Autolock al(observer_guard);
for(unsigned int i = 0; i < app_manager_observers.size(); i++)
{
app_manager_observers[i]->on_session_requested(app);
}
}
void ApplicationManager::notify_observers_about_session_born(int id, int stage_hint, const android::String8& desktop_file)
{
android::Mutex::Autolock al(observer_guard);
for(unsigned int i = 0; i < app_manager_observers.size(); i++)
{
app_manager_observers[i]->on_session_born(id, stage_hint, desktop_file);
}
}
void ApplicationManager::notify_observers_about_session_unfocused(int id, int stage_hint, const android::String8& desktop_file)
{
android::Mutex::Autolock al(observer_guard);
for(unsigned int i = 0; i < app_manager_observers.size(); i++)
{
app_manager_observers[i]->on_session_unfocused(id, stage_hint, desktop_file);
}
}
void ApplicationManager::notify_observers_about_session_focused(int id, int stage_hint, const android::String8& desktop_file)
{
android::Mutex::Autolock al(observer_guard);
for(unsigned int i = 0; i < app_manager_observers.size(); i++)
{
app_manager_observers[i]->on_session_focused(id, stage_hint, desktop_file);
}
}
void ApplicationManager::notify_observers_about_keyboard_geometry_changed(int x, int y, int width, int height)
{
android::Mutex::Autolock al(observer_guard);
for(unsigned int i = 0; i < app_manager_observers.size(); i++)
{
app_manager_observers[i]->on_keyboard_geometry_changed(x, y, width, height);
}
}
void ApplicationManager::notify_observers_about_session_requested_fullscreen(int id, int stage_hint, const android::String8& desktop_file)
{
android::Mutex::Autolock al(observer_guard);
for(unsigned int i = 0; i < app_manager_observers.size(); i++)
{
app_manager_observers[i]->on_session_requested_fullscreen(id, stage_hint, desktop_file);
}
}
void ApplicationManager::notify_observers_about_session_died(int id, int stage_hint, const android::String8& desktop_file)
{
android::Mutex::Autolock al(observer_guard);
for(unsigned int i = 0; i < app_manager_observers.size(); i++)
{
app_manager_observers[i]->on_session_died(id, stage_hint, desktop_file);
}
}
struct ClipboardService : public android::BnClipboardService
{
void set_content(const android::IClipboardService::Content& content)
{
this->content = content;
}
void get_content(android::IClipboardService::Content& content)
{
content = this->content;
}
android::IClipboardService::Content content;
};
}
}
int main(int argc, char** argv)
{
android::sp app_manager(new ubuntu::detail::ApplicationManager());
android::sp clipboard_service(new ubuntu::detail::ClipboardService());
// Register service
android::sp service_manager = android::defaultServiceManager();
if (android::NO_ERROR != service_manager->addService(
android::String16(android::IApplicationManager::exported_service_name()),
app_manager))
{
return EXIT_FAILURE;
}
if (android::NO_ERROR != service_manager->addService(
android::String16(android::IClipboardService::exported_service_name()),
clipboard_service))
{
return EXIT_FAILURE;
}
android::ProcessState::self()->startThreadPool();
android::IPCThreadState::self()->joinThreadPool();
}
platform-api-0.20+14.04.20140411/android/hybris/default_shell.h 0000644 0000153 0177776 00000002272 12322054725 024331 0 ustar pbuser nogroup 0000000 0000000 /*
* Copyright © 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* Authored by: Thomas Voß
*/
#ifndef DEFAULT_SHELL_H_
#define DEFAULT_SHELL_H_
#include "shell.h"
namespace ubuntu { namespace detail
{
class DefaultShell : public Shell
{
public:
static android::sp instance(const android::sp& app_manager)
{
static android::sp shell(new DefaultShell(app_manager));
return shell;
}
protected:
DefaultShell(const android::sp& app_manager) : Shell(app_manager)
{
}
};
}
}
#endif // DEFAULT_SHELL_H_
platform-api-0.20+14.04.20140411/android/hybris/shell.h 0000644 0000153 0177776 00000002206 12322054725 022622 0 ustar pbuser nogroup 0000000 0000000 /*
* Copyright © 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* Authored by: Thomas Voß
*/
#ifndef SHELL_H_
#define SHELL_H_
#include
namespace ubuntu { namespace detail
{
class ApplicationManager;
class Shell : public android::RefBase
{
public:
static android::sp instance();
protected:
Shell(const android::sp& app_manager) : app_manager(app_manager)
{
}
virtual ~Shell()
{
}
android::sp app_manager;
};
}
}
#endif // SHELL_H_
platform-api-0.20+14.04.20140411/android/hybris/ubuntu_application_api_for_hybris.cpp 0000644 0000153 0177776 00000107212 12322054725 031035 0 ustar pbuser nogroup 0000000 0000000 /*
* Copyright © 2012 Canonical Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* Authored by: Thomas Voß
*/
#include "application_manager.h"
#include "event_loop.h"
#include "input_consumer_thread.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#if ANDROID_VERSION_MAJOR==4 && ANDROID_VERSION_MINOR<=2
#include
#else
#include
#endif
#include
#include
#include
#include
namespace android
{
struct Clipboard : public ubuntu::application::ui::Clipboard
{
static sp access_clipboard_service()
{
static sp remote_instance;
if (remote_instance == NULL)
{
sp service_manager = defaultServiceManager();
sp service = service_manager->getService(
String16(IClipboardService::exported_service_name()));
remote_instance = new BpClipboardService(service);
}
return remote_instance;
}
void set_content(const Clipboard::Content& content)
{
IClipboardService::Content c;
c.mime_type = String8(content.mime_type);
c.data_size = content.data_size;
c.data = content.data;
access_clipboard_service()->set_content(c);
}
Clipboard::Content get_content()
{
IClipboardService::Content content;
access_clipboard_service()->get_content(content);
Clipboard::Content result(content.mime_type.string(),
content.data,
content.data_size);
memcpy(result.data, content.data, result.data_size);
return result;
}
};
struct Setup : public ubuntu::application::ui::Setup
{
Setup() : stage(ubuntu::application::ui::main_stage),
form_factor(ubuntu::application::ui::desktop_form_factor),
desktop_file("/usr/share/applications/shotwell.desktop")
{
}
static android::KeyedVector init_string_to_stage_hint_lut()
{
android::KeyedVector lut;
lut.add(android::String8("main_stage"), ubuntu::application::ui::main_stage);
lut.add(android::String8("side_stage"), ubuntu::application::ui::side_stage);
lut.add(android::String8("share_stage"), ubuntu::application::ui::share_stage);
return lut;
}
static ubuntu::application::ui::StageHint string_to_stage_hint(const android::String8& s)
{
static android::KeyedVector lut = init_string_to_stage_hint_lut();
return lut.valueFor(s);
}
static android::KeyedVector init_string_to_form_factor_hint_lut()
{
android::KeyedVector lut;
lut.add(android::String8("desktop"), ubuntu::application::ui::desktop_form_factor);
lut.add(android::String8("phone"), ubuntu::application::ui::phone_form_factor);
lut.add(android::String8("tablet"), ubuntu::application::ui::tablet_form_factor);
return lut;
}
static ubuntu::application::ui::FormFactorHint string_to_form_factor_hint(const android::String8& s)
{
static android::KeyedVector lut = init_string_to_form_factor_hint_lut();
return lut.valueFor(s);
}
ubuntu::application::ui::StageHint stage_hint()
{
return stage;
}
ubuntu::application::ui::FormFactorHint form_factor_hint()
{
return ubuntu::application::ui::desktop_form_factor;
}
const char* desktop_file_hint()
{
return desktop_file.string();
}
ubuntu::application::ui::StageHint stage;
ubuntu::application::ui::FormFactorHint form_factor;
android::String8 desktop_file;
};
static Setup::Ptr global_setup(new Setup());
struct PhysicalDisplayInfo : public ubuntu::application::ui::PhysicalDisplayInfo
{
explicit PhysicalDisplayInfo(size_t display_id) : display_id(SurfaceComposerClient::getBuiltInDisplay(display_id))
{
}
float horizontal_dpi()
{
DisplayInfo info;
SurfaceComposerClient::getDisplayInfo(display_id, &info);
return info.xdpi;
}
float vertical_dpi()
{
DisplayInfo info;
SurfaceComposerClient::getDisplayInfo(display_id, &info);
return info.ydpi;
}
int horizontal_resolution()
{
DisplayInfo info;
SurfaceComposerClient::getDisplayInfo(display_id, &info);
return info.w;
}
int vertical_resolution()
{
DisplayInfo info;
SurfaceComposerClient::getDisplayInfo(display_id, &info);
return info.h;
}
sp display_id;
};
struct UbuntuSurface : public ubuntu::application::ui::Surface
{
struct Observer
{
virtual ~Observer() {}
virtual void update() = 0;
};
sp client;
sp surface_control;
sp surface;
sp input_channel;
InputConsumer input_consumer;
sp looper;
PreallocatedInputEventFactory event_factory;
IApplicationManagerSession::SurfaceProperties properties;
bool is_visible_flag;
Observer* observer;
static int looper_callback(int receiveFd, int events, void* ctxt)
{
uint32_t consumeSeq;
bool result = true;
UbuntuSurface* s = static_cast(ctxt);
InputEvent* ev;
android::status_t status;
while((status = s->input_consumer.consume(&s->event_factory, true, -1, &consumeSeq, &ev)) != android::WOULD_BLOCK)
{
switch(status)
{
case OK:
result = true;
//printf("We have a client side event for process %d. \n", getpid());
s->translate_and_dispatch_event(ev);
s->input_consumer.sendFinishedSignal(consumeSeq, result);
break;
case INVALID_OPERATION:
result = true;
break;
case NO_MEMORY:
result = true;
break;
}
}
return result ? 1 : 0;
}
UbuntuSurface(const sp& client,
const sp& input_channel,
const sp& looper,
const ubuntu::application::ui::SurfaceProperties& props,
const ubuntu::application::ui::input::Listener::Ptr& listener,
Observer* observer = NULL)
: ubuntu::application::ui::Surface(listener),
client(client),
input_channel(input_channel),
input_consumer(input_channel),
looper(looper),
properties( {0, 0, 0, props.width-1, props.height-1}),
is_visible_flag(false),
observer(observer)
{
assert(client != NULL);
surface_control = client->createSurface(
String8(props.title),
props.width,
props.height,
PIXEL_FORMAT_RGBA_8888,
props.flags & ubuntu::application::ui::is_opaque_flag ? android::ISurfaceComposerClient::eOpaque : 0);
assert(surface_control != NULL);
surface = surface_control->getSurface();
assert(surface != NULL);
// Setup input channel
looper->addFd(input_channel->getFd(),
0,
ALOOPER_EVENT_INPUT,
looper_callback,
this);
}
~UbuntuSurface()
{
looper->removeFd(input_channel->getFd());
}
void translate_and_dispatch_event(const android::InputEvent* ev)
{
Event e;
switch(ev->getType())
{
case AINPUT_EVENT_TYPE_KEY:
{
const android::KeyEvent* kev = static_cast(ev);
e.type = KEY_EVENT_TYPE;
e.device_id = ev->getDeviceId();
e.source_id = ev->getSource();
e.action = kev->getAction();
e.flags = kev->getFlags();
e.meta_state = kev->getMetaState();
e.details.key.key_code = kev->getKeyCode();
e.details.key.scan_code = kev->getScanCode();
e.details.key.repeat_count = kev->getRepeatCount();
e.details.key.down_time = kev->getDownTime();
e.details.key.event_time = kev->getEventTime();
e.details.key.is_system_key = kev->isSystemKey();
break;
}
case AINPUT_EVENT_TYPE_MOTION:
const android::MotionEvent* mev = static_cast(ev);
e.type = MOTION_EVENT_TYPE;
e.device_id = ev->getDeviceId();
e.source_id = ev->getSource();
e.action = mev->getAction();
e.flags = mev->getFlags();
e.meta_state = mev->getMetaState();
e.details.motion.edge_flags = mev->getEdgeFlags();
e.details.motion.button_state = mev->getButtonState();
e.details.motion.x_offset = mev->getXOffset();
e.details.motion.y_offset = mev->getYOffset();
e.details.motion.x_precision = mev->getXPrecision();
e.details.motion.y_precision = mev->getYPrecision();
e.details.motion.down_time = mev->getDownTime();
e.details.motion.event_time = mev->getEventTime();
e.details.motion.pointer_count = mev->getPointerCount();
for(unsigned int i = 0; i < mev->getPointerCount(); i++)
{
e.details.motion.pointer_coordinates[i].id = mev->getPointerId(i);
e.details.motion.pointer_coordinates[i].x = mev->getX(i);
e.details.motion.pointer_coordinates[i].raw_x = mev->getRawX(i);
e.details.motion.pointer_coordinates[i].y = mev->getY(i);
e.details.motion.pointer_coordinates[i].raw_y = mev->getRawY(i);
e.details.motion.pointer_coordinates[i].touch_major = mev->getTouchMajor(i);
e.details.motion.pointer_coordinates[i].touch_minor = mev->getTouchMinor(i);
e.details.motion.pointer_coordinates[i].size = mev->getSize(i);
e.details.motion.pointer_coordinates[i].pressure = mev->getPressure(i);
e.details.motion.pointer_coordinates[i].orientation = mev->getOrientation(i);
}
break;
}
registered_input_listener()->on_new_event(e);
}
void set_layer(int layer)
{
client->openGlobalTransaction();
surface_control->setLayer(layer);
client->closeGlobalTransaction();
properties.layer = layer;
}
void set_visible(int id, bool visible)
{
sp service_manager = defaultServiceManager();
sp service = service_manager->getService(
String16(IApplicationManager::exported_service_name()));
BpApplicationManager app_manager(service);
ALOGI("%s: %s", __PRETTY_FUNCTION__, visible ? "true" : "false");
if (visible)
{
client->openGlobalTransaction();
ALOGI("surface_control->show(INT_MAX): %d id=%d", surface_control->show(), id);
client->closeGlobalTransaction();
if (id)
app_manager.focus_running_session_with_id(id);
}
else
{
client->openGlobalTransaction();
ALOGI("surface_control->hide(): %d", surface_control->hide());
client->closeGlobalTransaction();
}
}
void set_alpha(float alpha)
{
client->openGlobalTransaction();
surface_control->setAlpha(alpha);
client->closeGlobalTransaction();
if (observer)
observer->update();
}
void move_to(int x, int y)
{
client->openGlobalTransaction();
surface_control->setPosition(x, y);
client->closeGlobalTransaction();
properties.left = x;
properties.top = y;
properties.right += x;
properties.bottom += y;
if (observer)
observer->update();
}
void resize(int w, int h)
{
client->openGlobalTransaction();
surface_control->setSize(w, h);
client->closeGlobalTransaction();
properties.right = properties.left + w;
properties.bottom = properties.top + h;
if (observer)
observer->update();
}
int32_t get_id()
{
return -1;
}
EGLNativeWindowType to_native_window_type()
{
return surface.get();
}
};
struct Session : public ubuntu::application::ui::Session, public UbuntuSurface::Observer
{
struct ApplicationManagerSession : public BnApplicationManagerSession
{
ApplicationManagerSession(Session* parent) : parent(parent),
delegate()
{
}
// From IApplicationManagerSession
void raise_application_surfaces_to_layer(int layer)
{
ALOGI("%s: %d \n", __PRETTY_FUNCTION__, layer);
parent->raise_application_surfaces_to_layer(layer);
}
void raise_surface_to_layer(int32_t token, int layer)
{
ALOGI("Enter %s (%d): %d, %d", __PRETTY_FUNCTION__, getpid(), token, layer);
auto surface = parent->surfaces.valueFor(token);
if (surface != NULL)
{
ALOGI("\tFound surface for token: %d", token);
surface->set_layer(layer);
} else
{
ALOGI("\tFound NO surface for token: %d", token);
}
ALOGI("Leave %s (%d): %d, %d", __PRETTY_FUNCTION__, getpid(), token, layer);
}
SurfaceProperties query_surface_properties_for_token(int32_t token)
{
ALOGI("%s: %d \n", __PRETTY_FUNCTION__, token);
return parent->surfaces.valueFor(token)->properties;
}
void on_application_resumed()
{
if (delegate == NULL)
return;
delegate->on_application_resumed();
}
void on_application_about_to_stop()
{
if (delegate == NULL)
return;
delegate->on_application_about_to_stop();
}
void install_lifecycle_delegate(const ubuntu::application::LifecycleDelegate::Ptr& delegate)
{
this->delegate = delegate;
}
Session* parent;
ubuntu::application::LifecycleDelegate::Ptr delegate;
};
sp app_manager_session;
sp client;
sp looper;
sp event_loop;
Mutex surfaces_guard;
KeyedVector< int32_t, android::sp > surfaces;
Session(const ubuntu::application::ui::SessionCredentials& creds)
: app_manager_session(new ApplicationManagerSession(this)),
client(new android::SurfaceComposerClient()),
looper(new Looper(true)),
event_loop(new ubuntu::application::EventLoop(looper))
{
assert(client);
//============= This has to die =================
sp server_channel, client_channel;
InputChannel::openInputChannelPair(
String8("UbuntuApplicationUiSession"),
server_channel,
client_channel);
//printf("Created input channels: \n");
//printf("\t %d, %d, %d \n",
//server_channel->getFd());
//============= This has to die =================
sp service_manager = defaultServiceManager();
sp service = service_manager->getService(
String16(IApplicationManager::exported_service_name()));
BpApplicationManager app_manager(service);
app_manager.start_a_new_session(
creds.session_type(),
ubuntu::application::ui::Setup::instance()->stage_hint(),
String8(creds.application_name()),
String8(ubuntu::application::ui::Setup::instance()->desktop_file_hint()),
app_manager_session,
server_channel->getFd(),
creds.remote_pid());
android::ProcessState::self()->startThreadPool();
event_loop->run(__PRETTY_FUNCTION__, android::PRIORITY_URGENT_DISPLAY);
}
void install_lifecycle_delegate(const ubuntu::application::LifecycleDelegate::Ptr& delegate)
{
this->app_manager_session->install_lifecycle_delegate(delegate);
}
void update()
{
sp service_manager = defaultServiceManager();
sp service = service_manager->getService(
String16(IApplicationManager::exported_service_name()));
BpApplicationManager app_manager(service);
app_manager.request_update_for_session(app_manager_session);
}
ubuntu::application::ui::Surface::Ptr create_surface(
const ubuntu::application::ui::SurfaceProperties& props,
const ubuntu::application::ui::input::Listener::Ptr& listener)
{
sp service_manager = defaultServiceManager();
sp service = service_manager->getService(
String16(IApplicationManager::exported_service_name()));
BpApplicationManager app_manager(service);
sp server_channel, client_channel;
InputChannel::openInputChannelPair(
String8(props.title),
server_channel,
client_channel);
UbuntuSurface* surface = new UbuntuSurface(
client,
client_channel,
looper,
props,
listener,
this);
int32_t token;
{
Mutex::Autolock al(surfaces_guard);
token = next_surface_token();
surfaces.add(token, sp(surface));
}
app_manager.register_a_surface(
String8(props.title),
app_manager_session,
props.role,
token,
server_channel->getFd());
return ubuntu::application::ui::Surface::Ptr(surface);
}
int get_session_pid()
{
sp service_manager = defaultServiceManager();
sp service = service_manager->getService(
String16(IApplicationManager::exported_service_name()));
BpApplicationManager app_manager(service);
int pid = app_manager.get_session_pid(
app_manager_session
);
return pid;
}
void toggle_fullscreen_for_surface(const ubuntu::application::ui::Surface::Ptr& /*surface*/)
{
sp service_manager = defaultServiceManager();
sp service = service_manager->getService(
String16(IApplicationManager::exported_service_name()));
BpApplicationManager app_manager(service);
app_manager.request_fullscreen(
app_manager_session
);
}
void destroy_surface(
const ubuntu::application::ui::Surface::Ptr& surf)
{
(void) surf;
}
void raise_application_surfaces_to_layer(int layer)
{
Mutex::Autolock al(surfaces_guard);
ALOGI("%s: %d\n", __PRETTY_FUNCTION__, layer);
for(size_t i = 0; i < surfaces.size(); i++)
{
surfaces.valueAt(i)->set_layer(layer+i);
ALOGI("\tLayer: %d\n", layer+i);
}
}
int32_t next_surface_token()
{
static int32_t t = 0;
t++;
return t;
}
};
struct SessionProperties : public ubuntu::ui::SessionProperties
{
SessionProperties(int id, int stage_hint, const android::String8& desktop_file)
: id(id),
stage_hint(stage_hint),
desktop_file(desktop_file)
{
}
int application_instance_id() const
{
return id;
}
int application_stage_hint() const
{
return stage_hint;
}
const char* value_for_key(const char* key) const
{
return "lalelu";
}
virtual const char* desktop_file_hint() const
{
return desktop_file.string();
}
int id;
int stage_hint;
android::String8 desktop_file;
};
struct AMTaskController : public android::BnAMTaskController
{
void continue_task(uint32_t pid)
{
if (controller == NULL)
return;
controller->continue_task(static_cast(pid));
}
void suspend_task(uint32_t pid)
{
if (controller == NULL)
return;
controller->suspend_task(static_cast(pid));
}
void install_task_controller(const ubuntu::ui::TaskController::Ptr& controller)
{
printf("%s()\n", __PRETTY_FUNCTION__);
this->controller = controller;
sp service_manager = defaultServiceManager();
sp service = service_manager->getService(
String16(IApplicationManager::exported_service_name()));
BpApplicationManager app_manager(service);
app_manager.register_task_controller(android::sp