summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis Vidal <lvidal@cyngn.com>2016-06-06 11:55:01 -0700
committerLuis Vidal <lvidal@cyngn.com>2016-07-29 13:20:16 -0700
commita9cece56b4a8262c59ff104b9fb85ddf220ddd7d (patch)
treefc01d74a178f204dc655c19f034235e0c79c1969
parent325e080d66a6d8cac37cac499a17e7c360af212f (diff)
downloadandroid_packages_apps_Profiles-a9cece56b4a8262c59ff104b9fb85ddf220ddd7d.tar.gz
android_packages_apps_Profiles-a9cece56b4a8262c59ff104b9fb85ddf220ddd7d.tar.bz2
android_packages_apps_Profiles-a9cece56b4a8262c59ff104b9fb85ddf220ddd7d.zip
Ensures ProfileTrustAgent properly grants/revokes trust [1/2]
Keep track of WiFi network and BT connections to make sure the agent grants or revokes trust based on the active profile triggers Change-Id: Ifbe6a205f73b1ed0947f9e28af6449002bc4e79f TICKET: CYNGNOS-2719 (cherry picked from commit ea4e0f404b36afa8c37829dac0a8aea5b5a1a963)
-rw-r--r--AndroidManifest.xml3
-rw-r--r--src/org/cyanogenmod/profiles/ProfilesTrustAgent.java226
2 files changed, 212 insertions, 17 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index a3c0c13..ba1c758 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -21,6 +21,9 @@
<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"/>
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <uses-permission android:name="android.permission.BLUETOOTH" />
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
<application android:allowBackup="false"
android:label="@string/app_label"
diff --git a/src/org/cyanogenmod/profiles/ProfilesTrustAgent.java b/src/org/cyanogenmod/profiles/ProfilesTrustAgent.java
index c8b30d4..9c57709 100644
--- a/src/org/cyanogenmod/profiles/ProfilesTrustAgent.java
+++ b/src/org/cyanogenmod/profiles/ProfilesTrustAgent.java
@@ -16,20 +16,31 @@
package org.cyanogenmod.profiles;
-import android.app.admin.DevicePolicyManager;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.net.wifi.WifiSsid;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
+import android.os.UserHandle;
import android.service.trust.TrustAgentService;
+import android.util.ArraySet;
import android.util.Log;
-
import cyanogenmod.app.Profile;
import cyanogenmod.app.ProfileManager;
+import cyanogenmod.providers.CMSettings;
import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.Set;
/**
* Profiles Trust Agent
@@ -45,44 +56,69 @@ public class ProfilesTrustAgent extends TrustAgentService {
private static final int GRANT_DURATION_MS = 1000 * 60 * 5; // 5 minutes
private static final int MSG_UPDATE_STATE = 100;
+ private static final int MSG_ON_AGENT_CREATED = 101;
+ private static final int MSG_ON_TRIGGER_STATE_CHANGED = 102;
+ private static final int MSG_ON_USER_SWITCH = 103;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- mHandler.sendEmptyMessage(MSG_UPDATE_STATE);
+ final String action = intent.getAction();
+ if (ProfileManager.INTENT_ACTION_PROFILE_TRIGGER_STATE_CHANGED.equals(action)) {
+ mHandler.obtainMessage(MSG_ON_TRIGGER_STATE_CHANGED,
+ intent.getExtras()).sendToTarget();
+ } else if (Intent.ACTION_USER_FOREGROUND.equals(action)) {
+ mHandler.sendEmptyMessage(MSG_ON_USER_SWITCH);
+ } else {
+ mHandler.sendEmptyMessage(MSG_UPDATE_STATE);
+ }
}
};
private ProfileManager mProfileManager;
private ProfileHandler mHandler;
+ private SystemProfilesSettingsObserver mObserver;
@Override
public void onCreate() {
super.onCreate();
- mProfileManager = ProfileManager.getInstance(this);
- mHandler = new ProfileHandler(ProfilesTrustAgent.this);
-
- IntentFilter filter = new IntentFilter();
- filter.addAction(ProfileManager.INTENT_ACTION_PROFILE_SELECTED);
- filter.addAction(ProfileManager.INTENT_ACTION_PROFILE_UPDATED);
+ if (UserHandle.myUserId() == UserHandle.USER_OWNER) {
+ mProfileManager = ProfileManager.getInstance(this);
+ mHandler = new ProfileHandler(ProfilesTrustAgent.this);
- registerReceiver(mReceiver, filter);
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ProfileManager.INTENT_ACTION_PROFILE_SELECTED);
+ filter.addAction(ProfileManager.INTENT_ACTION_PROFILE_UPDATED);
+ filter.addAction(ProfileManager.INTENT_ACTION_PROFILE_TRIGGER_STATE_CHANGED);
+ filter.addAction(Intent.ACTION_USER_FOREGROUND);
- setManagingTrust(true);
+ registerReceiver(mReceiver, filter);
+ setManagingTrust(true);
+ mObserver = new SystemProfilesSettingsObserver(mHandler);
+ getContentResolver().registerContentObserver(
+ CMSettings.System.getUriFor(CMSettings.System.SYSTEM_PROFILES_ENABLED),
+ false, mObserver);
+ mHandler.sendEmptyMessage(MSG_ON_AGENT_CREATED);
+ }
}
@Override
public void onDestroy() {
- mHandler = null;
- mProfileManager = null;
- setManagingTrust(false);
- unregisterReceiver(mReceiver);
+ if (UserHandle.myUserId() == UserHandle.USER_OWNER) {
+ mHandler = null;
+ mProfileManager = null;
+ setManagingTrust(false);
+ unregisterReceiver(mReceiver);
+ getContentResolver().unregisterContentObserver(mObserver);
+ }
super.onDestroy();
}
@Override
public void onTrustTimeout() {
- mHandler.sendEmptyMessage(MSG_UPDATE_STATE);
+ if (UserHandle.myUserId() == UserHandle.USER_OWNER) {
+ mHandler.sendEmptyMessage(MSG_UPDATE_STATE);
+ }
}
private void handleApplyCurrentProfileState() {
@@ -109,6 +145,127 @@ public class ProfilesTrustAgent extends TrustAgentService {
}
}
+ private boolean shouldGrantTrustOnTriggerStateChanged(String triggerId, int triggerType,
+ int triggerState) {
+ final Profile activeProfile = mProfileManager.getActiveProfile();
+ if (activeProfile != null) {
+ final int lockMode = activeProfile.getScreenLockMode().getValue();
+ if (lockMode == Profile.LockMode.INSECURE) {
+ final List<Profile.ProfileTrigger> wifiTriggers
+ = activeProfile.getTriggersFromType(Profile.TriggerType.WIFI);
+ final List<Profile.ProfileTrigger> btTriggers
+ = activeProfile.getTriggersFromType(Profile.TriggerType.BLUETOOTH);
+ Set<String> onWiFiConnect = new ArraySet<>();
+ Set<String> onBTConnect = new ArraySet<>();
+
+ for (Profile.ProfileTrigger trigger : wifiTriggers) {
+ if (trigger.getState() == Profile.TriggerState.ON_CONNECT) {
+ onWiFiConnect.add(trigger.getId());
+ }
+ }
+ for (Profile.ProfileTrigger trigger : btTriggers) {
+ if (trigger.getState() == Profile.TriggerState.ON_CONNECT) {
+ onBTConnect.add(trigger.getId());
+ }
+ }
+
+ if (triggerState == Profile.TriggerState.ON_DISCONNECT) {
+ if (triggerType == Profile.TriggerType.BLUETOOTH
+ && onWiFiConnect.contains(getActiveSSID())) {
+ return true;
+ }
+
+ BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
+ Set<String> connectedBTDevices = new ArraySet<>();
+ for (BluetoothDevice device : pairedDevices) {
+ if (device.isConnected()) connectedBTDevices.add(device.getAddress());
+ }
+ for (Profile.ProfileTrigger btTrigger : btTriggers) {
+ if (connectedBTDevices.contains(btTrigger.getId())
+ && btTrigger.getState() == Profile.TriggerState.ON_CONNECT) {
+ return true;
+ }
+ }
+ } else if (triggerState == Profile.TriggerState.ON_CONNECT
+ && (onWiFiConnect.contains(triggerId) || onBTConnect.contains(triggerId))) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private boolean shouldGrantTrustOnCreate() {
+ final Profile activeProfile = mProfileManager.getActiveProfile();
+ if (activeProfile != null) {
+ final int lockMode = activeProfile.getScreenLockMode().getValue();
+ if (lockMode == Profile.LockMode.INSECURE) {
+ final String ssid = getActiveSSID();
+ for (Profile.ProfileTrigger trigger
+ : activeProfile.getTriggersFromType(Profile.TriggerType.WIFI)) {
+ if (trigger.getId().equals(ssid)
+ && trigger.getState() == Profile.TriggerState.ON_CONNECT) {
+ return true;
+ }
+ }
+ BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
+ Set<String> connectedBTDevices = new ArraySet<>();
+ for (BluetoothDevice device : pairedDevices) {
+ if (device.isConnected()) connectedBTDevices.add(device.getAddress());
+ }
+ for (Profile.ProfileTrigger trigger
+ : activeProfile.getTriggersFromType(Profile.TriggerType.BLUETOOTH)) {
+ if (connectedBTDevices.contains(trigger.getId())
+ && trigger.getState() == Profile.TriggerState.ON_CONNECT) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+ private String getActiveSSID() {
+ final WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+ WifiInfo wifiinfo = wifiManager.getConnectionInfo();
+ if (wifiinfo == null) {
+ return null;
+ }
+ WifiSsid ssid = wifiinfo.getWifiSsid();
+ if (ssid == null) {
+ return null;
+ }
+ return ssid.toString();
+ }
+
+ private void onTrustAgentCreated() {
+ // Check if we connected to a tracking WiFi network/BT device before this agent was created.
+ // The agent is created AFTER the user authenticates at boot or when a new lock screen
+ // (PIN, pattern, etc) is set
+ final Profile p = mProfileManager.getActiveProfile();
+ if (p != null && shouldGrantTrustOnCreate()) {
+ if (DEBUG) Log.w(TAG, "granting trust for profile " + p.getName());
+ grantTrust(getString(R.string.trust_by_profile), GRANT_DURATION_MS, false);
+ } else {
+ if (DEBUG) Log.w(TAG, "revoking trust.");
+ revokeTrust();
+ }
+ }
+
+ private void onTriggerStateChanged(String triggerId, int triggerType, int triggerState) {
+ final Profile p = mProfileManager.getActiveProfile();
+ if (p != null
+ && shouldGrantTrustOnTriggerStateChanged(triggerId, triggerType, triggerState)) {
+ if (DEBUG) Log.w(TAG, "granting trust for profile " + p.getName());
+ grantTrust(getString(R.string.trust_by_profile), GRANT_DURATION_MS, false);
+ } else {
+ if (DEBUG) Log.w(TAG, "revoking trust.");
+ revokeTrust();
+ }
+ }
+
private static class ProfileHandler extends Handler {
private final WeakReference<ProfilesTrustAgent> mService;
@@ -119,12 +276,47 @@ public class ProfilesTrustAgent extends TrustAgentService {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
- case MSG_UPDATE_STATE:
+ case MSG_UPDATE_STATE: {
ProfilesTrustAgent service = mService.get();
if (service != null) {
service.handleApplyCurrentProfileState();
}
break;
+ }
+ case MSG_ON_USER_SWITCH:
+ case MSG_ON_AGENT_CREATED: {
+ ProfilesTrustAgent service = mService.get();
+ if (service != null) {
+ service.onTrustAgentCreated();
+ }
+ break;
+ }
+ case MSG_ON_TRIGGER_STATE_CHANGED: {
+ ProfilesTrustAgent service = mService.get();
+ if (service != null && msg.obj != null) {
+ Bundle bundle = (Bundle) msg.obj;
+ final String id = bundle.getString(ProfileManager.EXTRA_TRIGGER_ID);
+ final int type = bundle.getInt(ProfileManager.EXTRA_TRIGGER_TYPE);
+ final int state = bundle.getInt(ProfileManager.EXTRA_TRIGGER_STATE);
+ service.onTriggerStateChanged(id, type, state);
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ private class SystemProfilesSettingsObserver extends ContentObserver {
+
+ public SystemProfilesSettingsObserver(Handler handler) {
+ super(handler);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ if (CMSettings.System.getUriFor(CMSettings.System.SYSTEM_PROFILES_ENABLED)
+ .compareTo(uri) == 0) {
+ mHandler.sendEmptyMessage(MSG_UPDATE_STATE);
}
}
}