Этой публикацией я бы хотел спровоцировать обсуждение проблемы, которая имеет место в системе Android: невозможность без ухищрений и хаков, методами, одобренными официальными гайдлайнами, создавать приложения для выполнения в защищенном окружении (kiosk-приложения).
Программное обеспечение kiosk должно обеспечивать защиту интернет-киоска (в данном случае — android-терминала) от несанкционированной активности. Киоск должен быть защищен от возможности вызова системных диалогов, доступа к настройкам устройства, доступа к файловой системе, и т.д.
Приложение, над которым я работаю, должно устанавливаться на терминалы, которые расположены в общественных местах, таких как торговые центры, кафе. Соответственно, любой пользователь по умолчанию должен считаться злоумышленником, который хочет зайти в настройки системы, изменить их, выполнить сброс системы или установить вредоносное приложение. Любые подобные действия система киоска должна пресекать.
Еще один класс подобных приложений — электронные меню в ресторанах. Я видел такие меню реализованные как на Android-устройствах, так и на iPad. Причем, и там и там использовалось одно и то же программное обеспечение, отличающееся только оформлением под конкретный ресторан. Так вот, устройство на iOS было на мой взгляд защищено лучше, т.к. в Android-варианте я смог без проблем войти в настройки, у меня была возможность их менять. В iOS все системные функции для пользователя были отключены и все, что мне предлагалось — ввести некий пин-код, который, видимо, разблокирует киоск.
Поиск по документации на developer.android.com не составил целостной картины по вопросу киоска. На stackoverflow периодически задаются подобные вопросы, и люди даже предлагают частные решения некоторых киоск-задач. Вот, например, некоторые из них:
1. Есть возможность запустить Activity или все приложение в полноэкранном режиме, скрыв statusbar. Google, кажется, называет это immersive mode. Также, можно временно скрыть системные кнопки (панель снизу экрана). Хорошо подходит для видеоплееров, игр, программ для презентаций. К сожалению, пользователь может «вытащить» статусбар обратно, проведя пальцем в верхней части экрана (swipe down), также вернуть панель системных кнопок.
2. Есть возможность получить экземпляр системной службы «statusbar» и при помощи reflection вызвать скрытый метод disable. К сожалению, сделав это мы получим SecurityException, т.к. скрывать статусбар позволено только системным пр��ложениям. Чтобы стать системным, необходимо подписать свое приложение ключом, полученным от разработчика устройства. Возможность такая есть не всегда.
Кроме того, вызов скрытого недокументированного метода — не очень хорошая идея. Видимо, разработчики системы неспроста не предоставили открытого интерфейса для этого метода.
3. Мы можем переопределить метод onBackPressed в Activity-классе, заблокировав системную кнопку «Назад». Мы можем повесить intent filter на действие HOME, перехватив системную кнопку «Домой». Но мы не можем перехватить действие системной кнопки «Recent».
4. Бороться с нажатием системной кнопки «Recent» или вызовом statusbar можно перехватом события «потеря фокуса». При потере нашим Activity фокуса, мы немедленно его возвращаем. К сожалению, между потерей и возвратом фокуса может пройти около секунды (может меньше, может больше — зависит от быстродействия системы) и пользователь может успеть зайти в меню настроек или снять наше приложение, или сделать что-то еще.
5. Мы можем вообще отключить системные кнопки редактированием файла /system/build.prop:
Но, во-первых, для этого нужен root-доступ, во-вторых, хотелось бы иметь возможность делать это программно (да, можно программно редактировать этот файл, предварительно перемонтировать read only filesystem, затем перезагрузить устройство, но это все-таки хак).
Выходит, что в Android отсутствует целостная концепция по созданию kiosk-приложений. Хотелось бы иметь отдельный раздел API, решающий поставленные вопросы. Хотелось бы иметь набор рекомендаций от Google по созданию таких приложений.
Да, я понимаю — создание подобных приложений накладывает дополнительную ответственность на разработчика. Это открывает дорогу создателям вирусов-локеров. Но как же эту проблему решили разработчики на других платформах?
Программное обеспечение kiosk должно обеспечивать защиту интернет-киоска (в данном случае — android-терминала) от несанкционированной активности. Киоск должен быть защищен от возможности вызова системных диалогов, доступа к настройкам устройства, доступа к файловой системе, и т.д.
Приложение, над которым я работаю, должно устанавливаться на терминалы, которые расположены в общественных местах, таких как торговые центры, кафе. Соответственно, любой пользователь по умолчанию должен считаться злоумышленником, который хочет зайти в настройки системы, изменить их, выполнить сброс системы или установить вредоносное приложение. Любые подобные действия система киоска должна пресекать.
Еще один класс подобных приложений — электронные меню в ресторанах. Я видел такие меню реализованные как на Android-устройствах, так и на iPad. Причем, и там и там использовалось одно и то же программное обеспечение, отличающееся только оформлением под конкретный ресторан. Так вот, устройство на iOS было на мой взгляд защищено лучше, т.к. в Android-варианте я смог без проблем войти в настройки, у меня была возможность их менять. В iOS все системные функции для пользователя были отключены и все, что мне предлагалось — ввести некий пин-код, который, видимо, разблокирует киоск.
Поиск по документации на developer.android.com не составил целостной картины по вопросу киоска. На stackoverflow периодически задаются подобные вопросы, и люди даже предлагают частные решения некоторых киоск-задач. Вот, например, некоторые из них:
1. Есть возможность запустить Activity или все приложение в полноэкранном режиме, скрыв statusbar. Google, кажется, называет это immersive mode. Также, можно временно скрыть системные кнопки (панель снизу экрана). Хорошо подходит для видеоплееров, игр, программ для презентаций. К сожалению, пользователь может «вытащить» статусбар обратно, проведя пальцем в верхней части экрана (swipe down), также вернуть панель системных кнопок.
2. Есть возможность получить экземпляр системной службы «statusbar» и при помощи reflection вызвать скрытый метод disable. К сожалению, сделав это мы получим SecurityException, т.к. скрывать статусбар позволено только системным пр��ложениям. Чтобы стать системным, необходимо подписать свое приложение ключом, полученным от разработчика устройства. Возможность такая есть не всегда.
Кроме того, вызов скрытого недокументированного метода — не очень хорошая идея. Видимо, разработчики системы неспроста не предоставили открытого интерфейса для этого метода.
3. Мы можем переопределить метод onBackPressed в Activity-классе, заблокировав системную кнопку «Назад». Мы можем повесить intent filter на действие HOME, перехватив системную кнопку «Домой». Но мы не можем перехватить действие системной кнопки «Recent».
4. Бороться с нажатием системной кнопки «Recent» или вызовом statusbar можно перехватом события «потеря фокуса». При потере нашим Activity фокуса, мы немедленно его возвращаем. К сожалению, между потерей и возвратом фокуса может пройти около секунды (может меньше, может больше — зависит от быстродействия системы) и пользователь может успеть зайти в меню настроек или снять наше приложение, или сделать что-то еще.
5. Мы можем вообще отключить системные кнопки редактированием файла /system/build.prop:
qemu.hw.mainkeys=0Но, во-первых, для этого нужен root-доступ, во-вторых, хотелось бы иметь возможность делать это программно (да, можно программно редактировать этот файл, предварительно перемонтировать read only filesystem, затем перезагрузить устройство, но это все-таки хак).
Выходит, что в Android отсутствует целостная концепция по созданию kiosk-приложений. Хотелось бы иметь отдельный раздел API, решающий поставленные вопросы. Хотелось бы иметь набор рекомендаций от Google по созданию таких приложений.
Да, я понимаю — создание подобных приложений накладывает дополнительную ответственность на разработчика. Это открывает дорогу создателям вирусов-локеров. Но как же эту проблему решили разработчики на других платформах?