diff options
8 files changed, 212 insertions, 23 deletions
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 2d61e6ec3bc5..d03f2e7aaccd 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -7442,6 +7442,8 @@ i <attr name="title" /> <!-- @SystemApi Summary for the same preference as the title. @hide --> <attr name="summary" /> + <!-- @SystemApi Whether trust agent can unlock a user profile @hide --> + <attr name="unlockProfile" format="boolean"/> </declare-styleable> <!-- =============================== --> @@ -8312,13 +8314,13 @@ i <attr name="color" /> </declare-styleable> - <!-- @hide Attributes which will be read by the Activity to intialize the + <!-- @hide Attributes which will be read by the Activity to intialize the base activity TaskDescription. --> <declare-styleable name="ActivityTaskDescription"> <!-- @hide From Theme.colorPrimary, used for the TaskDescription primary color. --> <attr name="colorPrimary" /> - <!-- @hide From Theme.colorBackground, used for the TaskDescription background + <!-- @hide From Theme.colorBackground, used for the TaskDescription background color. --> <attr name="colorBackground" /> </declare-styleable> diff --git a/packages/Keyguard/test/SampleTrustAgent/AndroidManifest.xml b/packages/Keyguard/test/SampleTrustAgent/AndroidManifest.xml index a7c91058283b..edcea0e64ac7 100644 --- a/packages/Keyguard/test/SampleTrustAgent/AndroidManifest.xml +++ b/packages/Keyguard/test/SampleTrustAgent/AndroidManifest.xml @@ -24,6 +24,7 @@ android:name=".SampleTrustAgent" android:label="@string/app_name" android:permission="android.permission.BIND_TRUST_AGENT" + android:directBootAware="true" android:exported="true"> <intent-filter> <action android:name="android.service.trust.TrustAgentService" /> diff --git a/packages/Keyguard/test/SampleTrustAgent/res/layout-v26/sample_trust_agent_settings.xml b/packages/Keyguard/test/SampleTrustAgent/res/layout-v26/sample_trust_agent_settings.xml new file mode 100644 index 000000000000..4669971e9be3 --- /dev/null +++ b/packages/Keyguard/test/SampleTrustAgent/res/layout-v26/sample_trust_agent_settings.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8"?> + +<!-- + ~ Copyright (C) 2014 The Android Open Source 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 + --> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <Button android:id="@+id/enable_trust" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="Grant trust for 30 seconds" /> + <Button android:id="@+id/revoke_trust" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="Revoke trust" /> + <Button android:id="@+id/crash" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="Crash" /> + <CheckBox android:id="@+id/managing_trust" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:text="Managing trust" /> + <CheckBox android:id="@+id/managing_trust_direct_boot" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:text="Managing trust direct boot"/> + + <CheckBox android:id="@+id/report_unlock_attempts" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:text="Report unlock attempts" /> + <CheckBox android:id="@+id/report_device_locked" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="8dp" + android:paddingBottom="8dp" + android:text="Report device locked or unlocked" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <Button android:id="@+id/check_device_locked" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Device locked?" /> + <TextView android:id="@+id/check_device_locked_result" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" /> + </LinearLayout> + +</LinearLayout>
\ No newline at end of file diff --git a/packages/Keyguard/test/SampleTrustAgent/res/xml-v26/sample_trust_agent.xml b/packages/Keyguard/test/SampleTrustAgent/res/xml-v26/sample_trust_agent.xml new file mode 100644 index 000000000000..26d5aa0c26f3 --- /dev/null +++ b/packages/Keyguard/test/SampleTrustAgent/res/xml-v26/sample_trust_agent.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2014 The Android Open Source 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:settingsActivity=".SampleTrustAgentSettings" + android:unlockProfile="true" /> diff --git a/packages/Keyguard/test/SampleTrustAgent/res/xml/sample_trust_agent.xml b/packages/Keyguard/test/SampleTrustAgent/res/xml/sample_trust_agent.xml index b363ab459c6d..6cd34bbab8e0 100644 --- a/packages/Keyguard/test/SampleTrustAgent/res/xml/sample_trust_agent.xml +++ b/packages/Keyguard/test/SampleTrustAgent/res/xml/sample_trust_agent.xml @@ -15,4 +15,4 @@ ~ limitations under the License --> <trust-agent xmlns:android="http://schemas.android.com/apk/res/android" - android:settingsActivity=".SampleTrustAgentSettings" /> + android:settingsActivity=".SampleTrustAgentSettings" /> diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java index b8f16e7929dc..4b50cf8c9fd5 100644 --- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java +++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgent.java @@ -22,6 +22,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.os.PersistableBundle; +import android.os.UserManager; import android.preference.PreferenceManager; import android.service.trust.TrustAgentService; import android.support.v4.content.LocalBroadcastManager; @@ -57,26 +58,47 @@ public class SampleTrustAgent extends TrustAgentService = "preference.report_unlock_attempts"; private static final String PREFERENCE_MANAGING_TRUST = "preference.managing_trust"; + private static final String PREFERENCE_MANAGING_TRUST_DIRECT_BOOT + = "preference.managing_trust_direct_boot"; private static final String PREFERENCE_REPORT_DEVICE_LOCKED = "preference.report_device_locked"; private static final String TAG = "SampleTrustAgent"; + private static final BroadcastReceiver mUnlockReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + + } + }; + + private boolean mIsUserUnlocked; + @Override public void onCreate() { super.onCreate(); + UserManager um = (UserManager) getSystemService(Context.USER_SERVICE); + mIsUserUnlocked = um.isUserUnlocked(); + Log.i(TAG,, "onCreate, is user unlocked=" + mIsUserUnlocked); mLocalBroadcastManager = LocalBroadcastManager.getInstance(this); IntentFilter filter = new IntentFilter(); filter.addAction(ACTION_GRANT_TRUST); filter.addAction(ACTION_REVOKE_TRUST); + if (!mIsUserUnlocked) { + filter.addAction(Intent.ACTION_BOOT_COMPLETED); + } mLocalBroadcastManager.registerReceiver(mReceiver, filter); if (ALLOW_EXTERNAL_BROADCASTS) { registerReceiver(mReceiver, filter); } - setManagingTrust(getIsManagingTrust(this)); - PreferenceManager.getDefaultSharedPreferences(this) - .registerOnSharedPreferenceChangeListener(this); + if (!mIsUserUnlocked) { + boolean trustManaged = getIsManagingTrustDirectBoot(this); + Log.i(TAG, "in Direct boot." + (trustManaged ? "manage" : "cannot manage") + "trust"); + setManagingTrust(getIsManagingTrustDirectBoot(this)); + } else { + onBootCompleted(); + } } @Override @@ -137,6 +159,12 @@ public class SampleTrustAgent extends TrustAgentService .unregisterOnSharedPreferenceChangeListener(this); } + private void onBootCompleted() { + PreferenceManager.getDefaultSharedPreferences(this) + .registerOnSharedPreferenceChangeListener(this); + setManagingTrust(getIsManagingTrust(this)); + } + private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -158,6 +186,9 @@ public class SampleTrustAgent extends TrustAgentService } } else if (ACTION_REVOKE_TRUST.equals(action)) { revokeTrust(); + } else if (intent.ACTION_BOOT_COMPLETED.equals(action)) { + Log.d(TAG, "User unlocked and boot completed."); + onBootCompleted(); } } }; @@ -203,6 +234,7 @@ public class SampleTrustAgent extends TrustAgentService public static void setIsManagingTrust(Context context, boolean enabled) { SharedPreferences sharedPreferences = PreferenceManager .getDefaultSharedPreferences(context); + Log.d("AAAA", "save manage trust preference. Enabled=" + enabled); sharedPreferences.edit().putBoolean(PREFERENCE_MANAGING_TRUST, enabled).apply(); } @@ -212,6 +244,21 @@ public class SampleTrustAgent extends TrustAgentService return sharedPreferences.getBoolean(PREFERENCE_MANAGING_TRUST, false); } + public static void setIsManagingTrustDirectBoot(Context context, boolean enabled) { + Context directBootContext = context.createDeviceProtectedStorageContext(); + SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(directBootContext); + Log.d("AAAA", "save to direct boot preference. Enabled=" + enabled); + sharedPreferences.edit().putBoolean(PREFERENCE_MANAGING_TRUST_DIRECT_BOOT, enabled).apply(); + } + + public static boolean getIsManagingTrustDirectBoot(Context context) { + Context directBootContext = context.createDeviceProtectedStorageContext(); + SharedPreferences sharedPreferences = PreferenceManager + .getDefaultSharedPreferences(directBootContext); + return sharedPreferences.getBoolean(PREFERENCE_MANAGING_TRUST_DIRECT_BOOT, false); + } + @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { if (PREFERENCE_MANAGING_TRUST.equals(key)) { diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java index 29b15cbff1fd..1b171693a6c9 100644 --- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java +++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java @@ -33,6 +33,7 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi private CheckBox mReportUnlockAttempts; private CheckBox mReportDeviceLocked; private CheckBox mManagingTrust; + private CheckBox mManagingTrustDirectBoot; private TextView mCheckDeviceLockedResult; private KeyguardManager mKeyguardManager; @@ -59,6 +60,8 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi mManagingTrust = (CheckBox) findViewById(R.id.managing_trust); mManagingTrust.setOnCheckedChangeListener(this); + mManagingTrustDirectBoot = (CheckBox) findViewById(R.id.managing_trust_direct_boot); + mManagingTrustDirectBoot.setOnCheckedChangeListener(this); mCheckDeviceLockedResult = (TextView) findViewById(R.id.check_device_locked_result); } @@ -68,6 +71,8 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi super.onResume(); mReportUnlockAttempts.setChecked(SampleTrustAgent.getReportUnlockAttempts(this)); mManagingTrust.setChecked(SampleTrustAgent.getIsManagingTrust(this)); + mManagingTrustDirectBoot.setChecked( + SampleTrustAgent.getIsManagingTrustDirectBoot(this)); updateTrustedState(); } @@ -94,6 +99,8 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi SampleTrustAgent.setIsManagingTrust(this, isChecked); } else if (buttonView == mReportDeviceLocked) { SampleTrustAgent.setReportDeviceLocked(this, isChecked); + } else if (buttonView == mManagingTrustDirectBoot) { + SampleTrustAgent.setIsManagingTrustDirectBoot(this, isChecked); } } diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 9d02940e21a5..cca8cc886246 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -169,7 +169,7 @@ public class TrustManagerService extends SystemService { CharSequence label; Drawable icon; ComponentName component; // service that implements ITrustAgent - ComponentName settings; // setting to launch to modify agent. + SettingsAttrs settings; // setting to launch to modify agent. TrustAgentWrapper agent; int userId; @@ -258,11 +258,6 @@ public class TrustManagerService extends SystemService { + ": switchToByUser=false"); continue; } - if (!StorageManager.isUserKeyUnlocked(userInfo.id)) { - if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id - + ": FDE still locked"); - continue; - } if (!mActivityManager.isUserRunning(userInfo.id)) { if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id + ": user not started"); @@ -273,13 +268,7 @@ public class TrustManagerService extends SystemService { + ": no secure credential"); continue; } - if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) { - if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id - + ": prevented by StrongAuthTracker = 0x" - + Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser( - userInfo.id))); - continue; - } + DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager(); int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id); final boolean disableTrustAgents = @@ -312,16 +301,49 @@ public class TrustManagerService extends SystemService { continue; } } - AgentInfo agentInfo = new AgentInfo(); agentInfo.component = name; agentInfo.userId = userInfo.id; if (!mActiveAgents.contains(agentInfo)) { agentInfo.label = resolveInfo.loadLabel(pm); agentInfo.icon = resolveInfo.loadIcon(pm); - agentInfo.settings = getSettingsComponentName(pm, resolveInfo); + agentInfo.settings = getSettingsAttrs(pm, resolveInfo); agentInfo.agent = new TrustAgentWrapper(mContext, this, new Intent().setComponent(name), userInfo.getUserHandle()); + } else { + int index = mActiveAgents.indexOf(agentInfo); + agentInfo = mActiveAgents.valueAt(index); + } + + boolean directUnlock = resolveInfo.serviceInfo.directBootAware + && agentInfo.settings.canUnlockProfile; + + if (directUnlock) { + if (DEBUG) Slog.d(TAG, "refreshAgentList: trustagent " + name + + "of user " + userInfo.id + "can unlock user profile."); + } + + if (!StorageManager.isUserKeyUnlocked(userInfo.id) + && !directUnlock) { + if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id + + "'s trust agent " + name + ": FDE still locked and " + + " the agent cannot unlock user profile."); + continue; + } + + if (!mStrongAuthTracker.canAgentsRunForUser(userInfo.id)) { + int flag = mStrongAuthTracker.getStrongAuthForUser(userInfo.id); + if (flag != StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT + || !directUnlock) { + if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id + + ": prevented by StrongAuthTracker = 0x" + + Integer.toHexString(mStrongAuthTracker.getStrongAuthForUser( + userInfo.id))); + continue; + } + } + + if (!mActiveAgents.contains(agentInfo)) { mActiveAgents.add(agentInfo); } else { obsoleteAgents.remove(agentInfo); @@ -468,10 +490,12 @@ public class TrustManagerService extends SystemService { refreshAgentList(userId); } - private ComponentName getSettingsComponentName(PackageManager pm, ResolveInfo resolveInfo) { + private SettingsAttrs getSettingsAttrs(PackageManager pm, ResolveInfo resolveInfo) { if (resolveInfo == null || resolveInfo.serviceInfo == null || resolveInfo.serviceInfo.metaData == null) return null; String cn = null; + boolean canUnlockProfile = false; + XmlResourceParser parser = null; Exception caughtException = null; try { @@ -496,6 +520,8 @@ public class TrustManagerService extends SystemService { TypedArray sa = res .obtainAttributes(attrs, com.android.internal.R.styleable.TrustAgent); cn = sa.getString(com.android.internal.R.styleable.TrustAgent_settingsActivity); + canUnlockProfile = sa.getBoolean( + com.android.internal.R.styleable.TrustAgent_unlockProfile, false); sa.recycle(); } catch (PackageManager.NameNotFoundException e) { caughtException = e; @@ -516,7 +542,7 @@ public class TrustManagerService extends SystemService { if (cn.indexOf('/') < 0) { cn = resolveInfo.serviceInfo.packageName + "/" + cn; } - return ComponentName.unflattenFromString(cn); + return new SettingsAttrs(ComponentName.unflattenFromString(cn), canUnlockProfile); } private ComponentName getComponentName(ResolveInfo resolveInfo) { @@ -554,6 +580,7 @@ public class TrustManagerService extends SystemService { private List<ResolveInfo> resolveAllowedTrustAgents(PackageManager pm, int userId) { List<ResolveInfo> resolveInfos = pm.queryIntentServicesAsUser(TRUST_AGENT_INTENT, + PackageManager.GET_META_DATA | PackageManager.MATCH_DIRECT_BOOT_AWARE | PackageManager.MATCH_DIRECT_BOOT_UNAWARE, userId); ArrayList<ResolveInfo> allowedAgents = new ArrayList<>(resolveInfos.size()); @@ -991,6 +1018,18 @@ public class TrustManagerService extends SystemService { } }; + private static class SettingsAttrs { + public ComponentName componentName; + public boolean canUnlockProfile; + + public SettingsAttrs( + ComponentName componentName, + boolean canUnlockProfile) { + this.componentName = componentName; + this.canUnlockProfile = canUnlockProfile; + } + }; + private class Receiver extends BroadcastReceiver { @Override |