diff options
author | Roman Birg <roman@cyngn.com> | 2015-04-20 18:12:53 -0700 |
---|---|---|
committer | Roman Birg <roman@cyngn.com> | 2015-04-24 12:30:55 -0700 |
commit | e77bc46f9d05b9c2f0eb2b37be2227e993fd6efa (patch) | |
tree | 7a96e8704d5942e98e3cddbdff76753e19ae19e4 | |
parent | afbe6e30000f63d61e6b88be40c8a0c0cce60b21 (diff) | |
download | android_packages_apps_Profiles-e77bc46f9d05b9c2f0eb2b37be2227e993fd6efa.tar.gz android_packages_apps_Profiles-e77bc46f9d05b9c2f0eb2b37be2227e993fd6efa.tar.bz2 android_packages_apps_Profiles-e77bc46f9d05b9c2f0eb2b37be2227e993fd6efa.zip |
ProfilesTrustAgent: initial implementation
Change-Id: I6aba123f81fd872e8ac6be532d8ec3995522daf2
Signed-off-by: Roman Birg <roman@cyngn.com>
-rw-r--r-- | Android.mk | 28 | ||||
-rw-r--r-- | AndroidManifest.xml | 47 | ||||
-rw-r--r-- | res/values/strings.xml | 22 | ||||
-rw-r--r-- | res/xml/profiles_trust_agent.xml | 20 | ||||
-rw-r--r-- | src/org/cyanogenmod/profiles/ProfilesTrustAgent.java | 126 | ||||
-rw-r--r-- | src/org/cyanogenmod/profiles/StartUpReceiver.java | 54 |
6 files changed, 297 insertions, 0 deletions
diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..b9ccf46 --- /dev/null +++ b/Android.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2015 The CyanogenMod Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-java-files-under, src) + +LOCAL_MODULE_TAGS := optional + +LOCAL_CERTIFICATE := platform + +LOCAL_PACKAGE_NAME := Profiles + +include $(BUILD_PACKAGE) diff --git a/AndroidManifest.xml b/AndroidManifest.xml new file mode 100644 index 0000000..deb4fc1 --- /dev/null +++ b/AndroidManifest.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License" + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.cyanogenmod.profiles"> + + <uses-permission android:name="android.permission.CONTROL_KEYGUARD"/> + <uses-permission android:name="android.permission.PROVIDE_TRUST_AGENT"/> + <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> + <uses-permission android:name="android.permission.ACCESS_KEYGUARD_SECURE_STORAGE"/> + + <application android:allowBackup="false" + android:label="@string/app_label" + android:requiredForAllUsers="true"> + + <service android:exported="true" + android:label="@string/app_label" + android:name=".ProfilesTrustAgent" + android:permission="android.permission.BIND_TRUST_AGENT"> + <intent-filter> + <action android:name="android.service.trust.TrustAgentService"/> + <category android:name="android.intent.category.DEFAULT"/> + </intent-filter> + <meta-data android:name="android.service.trust.trustagent" + android:resource="@xml/profiles_trust_agent"/> + </service> + + <receiver android:name=".StartUpReceiver"> + <intent-filter> + <action android:name="android.intent.action.BOOT_COMPLETED"/> + </intent-filter> + </receiver> + </application> +</manifest> diff --git a/res/values/strings.xml b/res/values/strings.xml new file mode 100644 index 0000000..9c77f2c --- /dev/null +++ b/res/values/strings.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License" + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<resources> + <string name="app_label">Profiles Trust Provider</string> + <string name="profile_trust_agent_title">Profiles Trust Agent</string> + <string name="profile_trust_agent_summary">Allows Profiles to temporarily disable lock screen protection</string> + <string name="trust_by_profile">Trusted by Profile</string> +</resources> diff --git a/res/xml/profiles_trust_agent.xml b/res/xml/profiles_trust_agent.xml new file mode 100644 index 0000000..3b4ee47 --- /dev/null +++ b/res/xml/profiles_trust_agent.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License" + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<trust-agent xmlns:android="http://schemas.android.com/apk/res/android" + android:title="@string/profile_trust_agent_title" + android:summary="@string/profile_trust_agent_summary" + /> diff --git a/src/org/cyanogenmod/profiles/ProfilesTrustAgent.java b/src/org/cyanogenmod/profiles/ProfilesTrustAgent.java new file mode 100644 index 0000000..41c50ae --- /dev/null +++ b/src/org/cyanogenmod/profiles/ProfilesTrustAgent.java @@ -0,0 +1,126 @@ +/* +* Copyright (C) 2015 The CyanogenMod Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.cyanogenmod.profiles; + +import android.app.Profile; +import android.app.ProfileManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.os.Handler; +import android.os.Message; +import android.service.trust.TrustAgentService; +import android.util.Log; + +import java.lang.ref.WeakReference; + +/** + * Profiles Trust Agent + * + * Watches for changes in the current {@link Profile} and grants or revokes trust (whether + * lock screen security is enforced). + */ +public class ProfilesTrustAgent extends TrustAgentService { + + private static final String TAG = ProfilesTrustAgent.class.getSimpleName(); + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + private static final int GRANT_DURATION_MS = 1000 * 60 * 5; // 5 minutes + + private static final int MSG_UPDATE_STATE = 100; + + private BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + mHandler.sendEmptyMessage(MSG_UPDATE_STATE); + } + }; + + private ProfileManager mProfileManager; + private ProfileHandler mHandler; + + @Override + public void onCreate() { + super.onCreate(); + mProfileManager = (ProfileManager) getSystemService(Context.PROFILE_SERVICE); + mHandler = new ProfileHandler(ProfilesTrustAgent.this); + + IntentFilter filter = new IntentFilter(); + filter.addAction(ProfileManager.INTENT_ACTION_PROFILE_SELECTED); + filter.addAction(ProfileManager.INTENT_ACTION_PROFILE_UPDATED); + + registerReceiver(mReceiver, filter); + + setManagingTrust(true); + } + + @Override + public void onDestroy() { + mHandler = null; + mProfileManager = null; + setManagingTrust(false); + unregisterReceiver(mReceiver); + super.onDestroy(); + } + + @Override + public void onTrustTimeout() { + mHandler.sendEmptyMessage(MSG_UPDATE_STATE); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return START_STICKY; + } + + private void handleApplyCurrentProfileState() { + Profile p = mProfileManager.getActiveProfile(); + int lockscreenState = p != null ? p.getScreenLockMode() : Profile.LockMode.DEFAULT; + switch (lockscreenState) { + case Profile.LockMode.DISABLE: + case Profile.LockMode.DEFAULT: + if (DEBUG) Log.w(TAG, "revoking trust."); + revokeTrust(); + break; + case Profile.LockMode.INSECURE: + if (DEBUG) Log.w(TAG, "granting trust for profile " + p.getName()); + grantTrust(getString(R.string.trust_by_profile), GRANT_DURATION_MS, false); + break; + } + } + + private static class ProfileHandler extends Handler { + private final WeakReference<ProfilesTrustAgent> mService; + + private ProfileHandler(ProfilesTrustAgent service) { + this.mService = new WeakReference<ProfilesTrustAgent>(service); + } + + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_UPDATE_STATE: + ProfilesTrustAgent service = mService.get(); + if (service != null) { + service.handleApplyCurrentProfileState(); + } + break; + } + } + } +} diff --git a/src/org/cyanogenmod/profiles/StartUpReceiver.java b/src/org/cyanogenmod/profiles/StartUpReceiver.java new file mode 100644 index 0000000..d33f407 --- /dev/null +++ b/src/org/cyanogenmod/profiles/StartUpReceiver.java @@ -0,0 +1,54 @@ +/* +* Copyright (C) 2015 The CyanogenMod Project +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.cyanogenmod.profiles; + +import android.content.BroadcastReceiver; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import com.android.internal.widget.LockPatternUtils; + +import java.util.List; + +/** + * Boot receiver which checks enables the ProfilesTrustAgent once, then disables itself. + * We only need to do this once to make sure we don't override if it was disabled at a later point. + */ +public class StartUpReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + // add ProfilesTrustAgent to list of trusted agents + LockPatternUtils lockUtils = new LockPatternUtils(context); + ComponentName profileTrustAgent = new ComponentName(context, ProfilesTrustAgent.class); + + List<ComponentName> enabledTrustAgents = lockUtils.getEnabledTrustAgents(); + if (!enabledTrustAgents.contains(profileTrustAgent)) { + enabledTrustAgents.add(profileTrustAgent); + lockUtils.setEnabledTrustAgents(enabledTrustAgents); + } + + // disable the receiver once it has enabled ProfilesTrustAgent + ComponentName name = new ComponentName(context, StartUpReceiver.class); + PackageManager pm = context.getPackageManager(); + pm.setComponentEnabledSetting(name, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, + PackageManager.DONT_KILL_APP); + } + +} |