TrustManagerService.java
- /*
- * 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
- */
- package com.android.server.trust;
- import android.Manifest;
- import android.annotation.UserIdInt;
- import android.app.ActivityManager;
- import android.app.admin.DevicePolicyManager;
- import android.app.trust.ITrustListener;
- import android.app.trust.ITrustManager;
- import android.content.BroadcastReceiver;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.content.pm.ApplicationInfo;
- import android.content.pm.PackageManager;
- import android.content.pm.ResolveInfo;
- import android.content.pm.UserInfo;
- import android.content.res.Resources;
- import android.content.res.TypedArray;
- import android.content.res.XmlResourceParser;
- import android.graphics.drawable.Drawable;
- import android.os.Binder;
- import android.os.Build;
- import android.os.DeadObjectException;
- import android.os.Handler;
- import android.os.IBinder;
- import android.os.Message;
- import android.os.PersistableBundle;
- import android.os.RemoteException;
- import android.os.SystemClock;
- import android.os.UserHandle;
- import android.os.UserManager;
- import android.os.storage.StorageManager;
- import android.provider.Settings;
- import android.service.trust.TrustAgentService;
- import android.text.TextUtils;
- import android.util.ArraySet;
- import android.util.AttributeSet;
- import android.util.Log;
- import android.util.Slog;
- import android.util.SparseBooleanArray;
- import android.util.Xml;
- import android.view.IWindowManager;
- import android.view.WindowManagerGlobal;
- import com.android.internal.annotations.GuardedBy;
- import com.android.internal.content.PackageMonitor;
- import com.android.internal.policy.IKeyguardDismissCallback;
- import com.android.internal.util.DumpUtils;
- import com.android.internal.widget.LockPatternUtils;
- import com.android.server.SystemService;
- import java.io.FileDescriptor;
- import java.io.IOException;
- import java.io.PrintWriter;
- import java.util.ArrayList;
- import java.util.List;
- import org.xmlpull.v1.XmlPullParser;
- import org.xmlpull.v1.XmlPullParserException;
- /**
- * Manages trust agents and trust listeners.
- *
- * It is responsible for binding to the enabled {@link android.service.trust.TrustAgentService}s
- * of each user and notifies them about events that are relevant to them.
- * It start and stops them based on the value of
- * {@link com.android.internal.widget.LockPatternUtils#getEnabledTrustAgents(int)}.
- *
- * It also keeps a set of {@link android.app.trust.ITrustListener}s that are notified whenever the
- * trust state changes for any user.
- *
- * Trust state and the setting of enabled agents is kept per user and each user has its own
- * instance of a {@link android.service.trust.TrustAgentService}.
- */
- public class TrustManagerService extends SystemService {
- private static final String TAG = "TrustManagerService";
- static final boolean DEBUG = Build.IS_DEBUGGABLE && Log.isLoggable(TAG, Log.VERBOSE);
- private static final Intent TRUST_AGENT_INTENT =
- new Intent(TrustAgentService.SERVICE_INTERFACE);
- private static final String PERMISSION_PROVIDE_AGENT = Manifest.permission.PROVIDE_TRUST_AGENT;
- private static final int MSG_REGISTER_LISTENER = 1;
- private static final int MSG_UNREGISTER_LISTENER = 2;
- private static final int MSG_DISPATCH_UNLOCK_ATTEMPT = 3;
- private static final int MSG_ENABLED_AGENTS_CHANGED = 4;
- private static final int MSG_KEYGUARD_SHOWING_CHANGED = 6;
- private static final int MSG_START_USER = 7;
- private static final int MSG_CLEANUP_USER = 8;
- private static final int MSG_SWITCH_USER = 9;
- private static final int MSG_FLUSH_TRUST_USUALLY_MANAGED = 10;
- private static final int MSG_UNLOCK_USER = 11;
- private static final int MSG_STOP_USER = 12;
- private static final int MSG_DISPATCH_UNLOCK_LOCKOUT = 13;
- private static final int MSG_REFRESH_DEVICE_LOCKED_FOR_USER = 14;
- private static final int TRUST_USUALLY_MANAGED_FLUSH_DELAY = 2 * 60 * 1000;
- private final ArraySet<AgentInfo> mActiveAgents = new ArraySet<>();
- private final ArrayList<ITrustListener> mTrustListeners = new ArrayList<>();
- private final Receiver mReceiver = new Receiver();
- /* package */ final TrustArchive mArchive = new TrustArchive();
- private final Context mContext;
- private final LockPatternUtils mLockPatternUtils;
- private final UserManager mUserManager;
- private final ActivityManager mActivityManager;
- @GuardedBy("mUserIsTrusted")
- private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray();
- @GuardedBy("mDeviceLockedForUser")
- private final SparseBooleanArray mDeviceLockedForUser = new SparseBooleanArray();
- @GuardedBy("mTrustUsuallyManagedForUser")
- private final SparseBooleanArray mTrustUsuallyManagedForUser = new SparseBooleanArray();
- // set to true only if user can skip bouncer
- @GuardedBy("mUsersUnlockedByFingerprint")
- private final SparseBooleanArray mUsersUnlockedByFingerprint = new SparseBooleanArray();
- private final StrongAuthTracker mStrongAuthTracker;
- private boolean mTrustAgentsCanRun = false;
- private int mCurrentUser = UserHandle.USER_SYSTEM;
- public TrustManagerService(Context context) {
- super(context);
- mContext = context;
- mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
- mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
- mLockPatternUtils = new LockPatternUtils(context);
- mStrongAuthTracker = new StrongAuthTracker(context);
- }
- @Override
- public void onStart() {
- publishBinderService(Context.TRUST_SERVICE, mService);
- }
- @Override
- public void onBootPhase(int phase) {
- if (isSafeMode()) {
- // No trust agents in safe mode.
- return;
- }
- if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
- mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true);
- mReceiver.register(mContext);
- mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
- } else if (phase == SystemService.PHASE_THIRD_PARTY_APPS_CAN_START) {
- mTrustAgentsCanRun = true;
- refreshAgentList(UserHandle.USER_ALL);
- refreshDeviceLockedForUser(UserHandle.USER_ALL);
- } else if (phase == SystemService.PHASE_BOOT_COMPLETED) {
- maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_SYSTEM);
- }
- }
- // Agent management
- private static final class AgentInfo {
- CharSequence label;
- Drawable icon;
- ComponentName component; // service that implements ITrustAgent
- SettingsAttrs settings; // setting to launch to modify agent.
- TrustAgentWrapper agent;
- int userId;
- @Override
- public boolean equals(Object other) {
- if (!(other instanceof AgentInfo)) {
- return false;
- }
- AgentInfo o = (AgentInfo) other;
- return component.equals(o.component) && userId == o.userId;
- }
- @Override
- public int hashCode() {
- return component.hashCode() * 31 + userId;
- }
- }
- private void updateTrustAll() {
- List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
- for (UserInfo userInfo : userInfos) {
- updateTrust(userInfo.id, 0);
- }
- }
- public void updateTrust(int userId, int flags) {
- boolean managed = aggregateIsTrustManaged(userId);
- dispatchOnTrustManagedChanged(managed, userId);
- if (mStrongAuthTracker.isTrustAllowedForUser(userId)
- && isTrustUsuallyManagedInternal(userId) != managed) {
- updateTrustUsuallyManaged(userId, managed);
- }
- boolean trusted = aggregateIsTrusted(userId);
- boolean changed;
- synchronized (mUserIsTrusted) {
- changed = mUserIsTrusted.get(userId) != trusted;
- mUserIsTrusted.put(userId, trusted);
- }
- dispatchOnTrustChanged(trusted, userId, flags);
- if (changed) {
- refreshDeviceLockedForUser(userId);
- }
- }
- private void updateTrustUsuallyManaged(int userId, boolean managed) {
- synchronized (mTrustUsuallyManagedForUser) {
- mTrustUsuallyManagedForUser.put(userId, managed);
- }
- // Wait a few minutes before committing to flash, in case the trust agent is transiently not
- // managing trust (crashed, needs to acknowledge DPM restrictions, etc).
- mHandler.removeMessages(MSG_FLUSH_TRUST_USUALLY_MANAGED);
- mHandler.sendMessageDelayed(
- mHandler.obtainMessage(MSG_FLUSH_TRUST_USUALLY_MANAGED),
- TRUST_USUALLY_MANAGED_FLUSH_DELAY);
- }
- public long addEscrowToken(byte[] token, int userId) {
- return mLockPatternUtils.addEscrowToken(token, userId);
- }
- public boolean removeEscrowToken(long handle, int userId) {
- return mLockPatternUtils.removeEscrowToken(handle, userId);
- }
- public boolean isEscrowTokenActive(long handle, int userId) {
- return mLockPatternUtils.isEscrowTokenActive(handle, userId);
- }
- public void unlockUserWithToken(long handle, byte[] token, int userId) {
- mLockPatternUtils.unlockUserWithToken(handle, token, userId);
- }
- void showKeyguardErrorMessage(CharSequence message) {
- dispatchOnTrustError(message);
- }
- void refreshAgentList(int userIdOrAll) {
- if (DEBUG) Slog.d(TAG, "refreshAgentList(" + userIdOrAll + ")");
- if (!mTrustAgentsCanRun) {
- return;
- }
- if (userIdOrAll != UserHandle.USER_ALL && userIdOrAll < UserHandle.USER_SYSTEM) {
- Log.e(TAG, "refreshAgentList(userId=" + userIdOrAll + "): Invalid user handle,"
- + " must be USER_ALL or a specific user.", new Throwable("here"));
- userIdOrAll = UserHandle.USER_ALL;
- }
- PackageManager pm = mContext.getPackageManager();
- List<UserInfo> userInfos;
- if (userIdOrAll == UserHandle.USER_ALL) {
- userInfos = mUserManager.getUsers(true /* excludeDying */);
- } else {
- userInfos = new ArrayList<>();
- userInfos.add(mUserManager.getUserInfo(userIdOrAll));
- }
- LockPatternUtils lockPatternUtils = mLockPatternUtils;
- ArraySet<AgentInfo> obsoleteAgents = new ArraySet<>();
- obsoleteAgents.addAll(mActiveAgents);
- for (UserInfo userInfo : userInfos) {
- if (userInfo == null || userInfo.partial || !userInfo.isEnabled()
- || userInfo.guestToRemove) continue;
- if (!userInfo.supportsSwitchToByUser()) {
- if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
- + ": switchToByUser=false");
- continue;
- }
- if (!mActivityManager.isUserRunning(userInfo.id)) {
- if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
- + ": user not started");
- continue;
- }
- if (!lockPatternUtils.isSecure(userInfo.id)) {
- if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
- + ": no secure credential");
- continue;
- }
- DevicePolicyManager dpm = lockPatternUtils.getDevicePolicyManager();
- int disabledFeatures = dpm.getKeyguardDisabledFeatures(null, userInfo.id);
- final boolean disableTrustAgents =
- (disabledFeatures & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0;
- List<ComponentName> enabledAgents = lockPatternUtils.getEnabledTrustAgents(userInfo.id);
- if (enabledAgents == null) {
- if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
- + ": no agents enabled by user");
- continue;
- }
- List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userInfo.id);
- for (ResolveInfo resolveInfo : resolveInfos) {
- ComponentName name = getComponentName(resolveInfo);
- if (!enabledAgents.contains(name)) {
- if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
- + name.flattenToShortString() + " u"+ userInfo.id
- + ": not enabled by user");
- continue;
- }
- if (disableTrustAgents) {
- List<PersistableBundle> config =
- dpm.getTrustAgentConfiguration(null /* admin */, name, userInfo.id);
- // Disable agent if no features are enabled.
- if (config == null || config.isEmpty()) {
- if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping "
- + name.flattenToShortString() + " u"+ userInfo.id
- + ": not allowed by DPM");
- 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 = getSettingsAttrs(pm, resolveInfo);
- } 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 (!mUserManager.isUserUnlockingOrUnlocked(userInfo.id)
- && !directUnlock) {
- if (DEBUG) Slog.d(TAG, "refreshAgentList: skipping user " + userInfo.id
- + "'s trust agent " + name + ": FBE 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_LOCKOUT) {
- 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 (agentInfo.agent == null) {
- agentInfo.agent = new TrustAgentWrapper(mContext, this,
- new Intent().setComponent(name), userInfo.getUserHandle());
- }
- if (!mActiveAgents.contains(agentInfo)) {
- mActiveAgents.add(agentInfo);
- } else {
- obsoleteAgents.remove(agentInfo);
- }
- }
- }
- boolean trustMayHaveChanged = false;
- for (int i = 0; i < obsoleteAgents.size(); i++) {
- AgentInfo info = obsoleteAgents.valueAt(i);
- if (userIdOrAll == UserHandle.USER_ALL || userIdOrAll == info.userId) {
- if (info.agent.isManagingTrust()) {
- trustMayHaveChanged = true;
- }
- info.agent.destroy();
- mActiveAgents.remove(info);
- }
- }
- if (trustMayHaveChanged) {
- if (userIdOrAll == UserHandle.USER_ALL) {
- updateTrustAll();
- } else {
- updateTrust(userIdOrAll, 0);
- }
- }
- }
- boolean isDeviceLockedInner(int userId) {
- synchronized (mDeviceLockedForUser) {
- return mDeviceLockedForUser.get(userId, true);
- }
- }
- private void refreshDeviceLockedForUser(int userId) {
- if (userId != UserHandle.USER_ALL && userId < UserHandle.USER_SYSTEM) {
- Log.e(TAG, "refreshDeviceLockedForUser(userId=" + userId + "): Invalid user handle,"
- + " must be USER_ALL or a specific user.", new Throwable("here"));
- userId = UserHandle.USER_ALL;
- }
- List<UserInfo> userInfos;
- if (userId == UserHandle.USER_ALL) {
- userInfos = mUserManager.getUsers(true /* excludeDying */);
- } else {
- userInfos = new ArrayList<>();
- userInfos.add(mUserManager.getUserInfo(userId));
- }
- IWindowManager wm = WindowManagerGlobal.getWindowManagerService();
- for (int i = 0; i < userInfos.size(); i++) {
- UserInfo info = userInfos.get(i);
- if (info == null || info.partial || !info.isEnabled() || info.guestToRemove
- || !info.supportsSwitchToByUser()) {
- continue;
- }
- int id = info.id;
- boolean secure = mLockPatternUtils.isSecure(id);
- boolean trusted = aggregateIsTrusted(id);
- boolean showingKeyguard = true;
- boolean fingerprintAuthenticated = false;
- if (mCurrentUser == id) {
- synchronized(mUsersUnlockedByFingerprint) {
- fingerprintAuthenticated = mUsersUnlockedByFingerprint.get(id, false);
- }
- try {
- showingKeyguard = wm.isKeyguardLocked();
- } catch (RemoteException e) {
- }
- }
- boolean deviceLocked = secure && showingKeyguard && !trusted &&
- !fingerprintAuthenticated;
- setDeviceLockedForUser(id, deviceLocked);
- }
- }
- private void setDeviceLockedForUser(@UserIdInt int userId, boolean locked) {
- final boolean changed;
- synchronized (mDeviceLockedForUser) {
- changed = isDeviceLockedInner(userId) != locked;
- mDeviceLockedForUser.put(userId, locked);
- }
- if (changed) {
- dispatchDeviceLocked(userId, locked);
- }
- }
- private void dispatchDeviceLocked(int userId, boolean isLocked) {
- for (int i = 0; i < mActiveAgents.size(); i++) {
- AgentInfo agent = mActiveAgents.valueAt(i);
- if (agent.userId == userId) {
- if (isLocked) {
- agent.agent.onDeviceLocked();
- } else{
- agent.agent.onDeviceUnlocked();
- }
- }
- }
- }
- void updateDevicePolicyFeatures() {
- boolean changed = false;
- for (int i = 0; i < mActiveAgents.size(); i++) {
- AgentInfo info = mActiveAgents.valueAt(i);
- if (info.agent.isConnected()) {
- info.agent.updateDevicePolicyFeatures();
- changed = true;
- }
- }
- if (changed) {
- mArchive.logDevicePolicyChanged();
- }
- }
- private void removeAgentsOfPackage(String packageName) {
- boolean trustMayHaveChanged = false;
- for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
- AgentInfo info = mActiveAgents.valueAt(i);
- if (packageName.equals(info.component.getPackageName())) {
- Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
- if (info.agent.isManagingTrust()) {
- trustMayHaveChanged = true;
- }
- info.agent.destroy();
- mActiveAgents.removeAt(i);
- }
- }
- if (trustMayHaveChanged) {
- updateTrustAll();
- }
- }
- public void resetAgent(ComponentName name, int userId) {
- boolean trustMayHaveChanged = false;
- for (int i = mActiveAgents.size() - 1; i >= 0; i--) {
- AgentInfo info = mActiveAgents.valueAt(i);
- if (name.equals(info.component) && userId == info.userId) {
- Log.i(TAG, "Resetting agent " + info.component.flattenToShortString());
- if (info.agent.isManagingTrust()) {
- trustMayHaveChanged = true;
- }
- info.agent.destroy();
- mActiveAgents.removeAt(i);
- }
- }
- if (trustMayHaveChanged) {
- updateTrust(userId, 0);
- }
- refreshAgentList(userId);
- }
- 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 {
- parser = resolveInfo.serviceInfo.loadXmlMetaData(pm,
- TrustAgentService.TRUST_AGENT_META_DATA);
- if (parser == null) {
- Slog.w(TAG, "Can't find " + TrustAgentService.TRUST_AGENT_META_DATA + " meta-data");
- return null;
- }
- Resources res = pm.getResourcesForApplication(resolveInfo.serviceInfo.applicationInfo);
- AttributeSet attrs = Xml.asAttributeSet(parser);
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && type != XmlPullParser.START_TAG) {
- // Drain preamble.
- }
- String nodeName = parser.getName();
- if (!"trust-agent".equals(nodeName)) {
- Slog.w(TAG, "Meta-data does not start with trust-agent tag");
- return null;
- }
- 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;
- } catch (IOException e) {
- caughtException = e;
- } catch (XmlPullParserException e) {
- caughtException = e;
- } finally {
- if (parser != null) parser.close();
- }
- if (caughtException != null) {
- Slog.w(TAG, "Error parsing : " + resolveInfo.serviceInfo.packageName, caughtException);
- return null;
- }
- if (cn == null) {
- return null;
- }
- if (cn.indexOf('/') < 0) {
- cn = resolveInfo.serviceInfo.packageName + "/" + cn;
- }
- return new SettingsAttrs(ComponentName.unflattenFromString(cn), canUnlockProfile);
- }
- private ComponentName getComponentName(ResolveInfo resolveInfo) {
- if (resolveInfo == null || resolveInfo.serviceInfo == null) return null;
- return new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
- }
- private void maybeEnableFactoryTrustAgents(LockPatternUtils utils, int userId) {
- if (0 != Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.TRUST_AGENTS_INITIALIZED, 0, userId)) {
- return;
- }
- PackageManager pm = mContext.getPackageManager();
- List<ResolveInfo> resolveInfos = resolveAllowedTrustAgents(pm, userId);
- ComponentName defaultAgent = getDefaultFactoryTrustAgent(mContext);
- boolean shouldUseDefaultAgent = defaultAgent != null;
- ArraySet<ComponentName> discoveredAgents = new ArraySet<>();
- if (shouldUseDefaultAgent) {
- discoveredAgents.add(defaultAgent);
- Log.i(TAG, "Enabling " + defaultAgent + " because it is a default agent.");
- } else { // A default agent is not set; perform regular trust agent discovery
- for (ResolveInfo resolveInfo : resolveInfos) {
- ComponentName componentName = getComponentName(resolveInfo);
- int applicationInfoFlags = resolveInfo.serviceInfo.applicationInfo.flags;
- if ((applicationInfoFlags & ApplicationInfo.FLAG_SYSTEM) == 0) {
- Log.i(TAG, "Leaving agent " + componentName + " disabled because package "
- + "is not a system package.");
- continue;
- }
- discoveredAgents.add(componentName);
- }
- }
- List<ComponentName> previouslyEnabledAgents = utils.getEnabledTrustAgents(userId);
- if (previouslyEnabledAgents != null) {
- discoveredAgents.addAll(previouslyEnabledAgents);
- }
- utils.setEnabledTrustAgents(discoveredAgents, userId);
- Settings.Secure.putIntForUser(mContext.getContentResolver(),
- Settings.Secure.TRUST_AGENTS_INITIALIZED, 1, userId);
- }
- /**
- * Returns the {@link ComponentName} for the default trust agent, or {@code null} if there
- * is no trust agent set.
- */
- private static ComponentName getDefaultFactoryTrustAgent(Context context) {
- String defaultTrustAgent = context.getResources()
- .getString(com.android.internal.R.string.config_defaultTrustAgent);
- if (TextUtils.isEmpty(defaultTrustAgent)) {
- return null;
- }
- return ComponentName.unflattenFromString(defaultTrustAgent);
- }
- 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());
- for (ResolveInfo resolveInfo : resolveInfos) {
- if (resolveInfo.serviceInfo == null) continue;
- if (resolveInfo.serviceInfo.applicationInfo == null) continue;
- String packageName = resolveInfo.serviceInfo.packageName;
- if (pm.checkPermission(PERMISSION_PROVIDE_AGENT, packageName)
- != PackageManager.PERMISSION_GRANTED) {
- ComponentName name = getComponentName(resolveInfo);
- Log.w(TAG, "Skipping agent " + name + " because package does not have"
- + " permission " + PERMISSION_PROVIDE_AGENT + ".");
- continue;
- }
- allowedAgents.add(resolveInfo);
- }
- return allowedAgents;
- }
- // Agent dispatch and aggregation
- private boolean aggregateIsTrusted(int userId) {
- if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
- return false;
- }
- for (int i = 0; i < mActiveAgents.size(); i++) {
- AgentInfo info = mActiveAgents.valueAt(i);
- if (info.userId == userId) {
- if (info.agent.isTrusted()) {
- return true;
- }
- }
- }
- return false;
- }
- private boolean aggregateIsTrustManaged(int userId) {
- if (!mStrongAuthTracker.isTrustAllowedForUser(userId)) {
- return false;
- }
- for (int i = 0; i < mActiveAgents.size(); i++) {
- AgentInfo info = mActiveAgents.valueAt(i);
- if (info.userId == userId) {
- if (info.agent.isManagingTrust()) {
- return true;
- }
- }
- }
- return false;
- }
- private void dispatchUnlockAttempt(boolean successful, int userId) {
- if (successful) {
- mStrongAuthTracker.allowTrustFromUnlock(userId);
- }
- for (int i = 0; i < mActiveAgents.size(); i++) {
- AgentInfo info = mActiveAgents.valueAt(i);
- if (info.userId == userId) {
- info.agent.onUnlockAttempt(successful);
- }
- }
- }
- private void dispatchUnlockLockout(int timeoutMs, int userId) {
- for (int i = 0; i < mActiveAgents.size(); i++) {
- AgentInfo info = mActiveAgents.valueAt(i);
- if (info.userId == userId) {
- info.agent.onUnlockLockout(timeoutMs);
- }
- }
- }
- // Listeners
- private void addListener(ITrustListener listener) {
- for (int i = 0; i < mTrustListeners.size(); i++) {
- if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
- return;
- }
- }
- mTrustListeners.add(listener);
- updateTrustAll();
- }
- private void removeListener(ITrustListener listener) {
- for (int i = 0; i < mTrustListeners.size(); i++) {
- if (mTrustListeners.get(i).asBinder() == listener.asBinder()) {
- mTrustListeners.remove(i);
- return;
- }
- }
- }
- private void dispatchOnTrustChanged(boolean enabled, int userId, int flags) {
- if (DEBUG) {
- Log.i(TAG, "onTrustChanged(" + enabled + ", " + userId + ", 0x"
- + Integer.toHexString(flags) + ")");
- }
- if (!enabled) flags = 0;
- for (int i = 0; i < mTrustListeners.size(); i++) {
- try {
- mTrustListeners.get(i).onTrustChanged(enabled, userId, flags);
- } catch (DeadObjectException e) {
- Slog.d(TAG, "Removing dead TrustListener.");
- mTrustListeners.remove(i);
- i--;
- } catch (RemoteException e) {
- Slog.e(TAG, "Exception while notifying TrustListener.", e);
- }
- }
- }
- private void dispatchOnTrustManagedChanged(boolean managed, int userId) {
- if (DEBUG) {
- Log.i(TAG, "onTrustManagedChanged(" + managed + ", " + userId + ")");
- }
- for (int i = 0; i < mTrustListeners.size(); i++) {
- try {
- mTrustListeners.get(i).onTrustManagedChanged(managed, userId);
- } catch (DeadObjectException e) {
- Slog.d(TAG, "Removing dead TrustListener.");
- mTrustListeners.remove(i);
- i--;
- } catch (RemoteException e) {
- Slog.e(TAG, "Exception while notifying TrustListener.", e);
- }
- }
- }
- private void dispatchOnTrustError(CharSequence message) {
- if (DEBUG) {
- Log.i(TAG, "onTrustError(" + message + ")");
- }
- for (int i = 0; i < mTrustListeners.size(); i++) {
- try {
- mTrustListeners.get(i).onTrustError(message);
- } catch (DeadObjectException e) {
- Slog.d(TAG, "Removing dead TrustListener.");
- mTrustListeners.remove(i);
- i--;
- } catch (RemoteException e) {
- Slog.e(TAG, "Exception while notifying TrustListener.", e);
- }
- }
- }
- // User lifecycle
- @Override
- public void onStartUser(int userId) {
- mHandler.obtainMessage(MSG_START_USER, userId, 0, null).sendToTarget();
- }
- @Override
- public void onCleanupUser(int userId) {
- mHandler.obtainMessage(MSG_CLEANUP_USER, userId, 0, null).sendToTarget();
- }
- @Override
- public void onSwitchUser(int userId) {
- mHandler.obtainMessage(MSG_SWITCH_USER, userId, 0, null).sendToTarget();
- }
- @Override
- public void onUnlockUser(int userId) {
- mHandler.obtainMessage(MSG_UNLOCK_USER, userId, 0, null).sendToTarget();
- }
- @Override
- public void onStopUser(@UserIdInt int userId) {
- mHandler.obtainMessage(MSG_STOP_USER, userId, 0, null).sendToTarget();
- }
- // Plumbing
- private final IBinder mService = new ITrustManager.Stub() {
- @Override
- public void reportUnlockAttempt(boolean authenticated, int userId) throws RemoteException {
- enforceReportPermission();
- mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_ATTEMPT, authenticated ? 1 : 0, userId)
- .sendToTarget();
- }
- @Override
- public void reportUnlockLockout(int timeoutMs, int userId) throws RemoteException {
- enforceReportPermission();
- mHandler.obtainMessage(MSG_DISPATCH_UNLOCK_LOCKOUT, timeoutMs, userId)
- .sendToTarget();
- }
- @Override
- public void reportEnabledTrustAgentsChanged(int userId) throws RemoteException {
- enforceReportPermission();
- // coalesce refresh messages.
- mHandler.removeMessages(MSG_ENABLED_AGENTS_CHANGED);
- mHandler.sendEmptyMessage(MSG_ENABLED_AGENTS_CHANGED);
- }
- @Override
- public void reportKeyguardShowingChanged() throws RemoteException {
- enforceReportPermission();
- // coalesce refresh messages.
- mHandler.removeMessages(MSG_KEYGUARD_SHOWING_CHANGED);
- mHandler.sendEmptyMessage(MSG_KEYGUARD_SHOWING_CHANGED);
- // Make sure handler processes the message before returning, such that isDeviceLocked
- // after this call will retrieve the correct value.
- mHandler.runWithScissors(() -> {}, 0);
- }
- @Override
- public void registerTrustListener(ITrustListener trustListener) throws RemoteException {
- enforceListenerPermission();
- mHandler.obtainMessage(MSG_REGISTER_LISTENER, trustListener).sendToTarget();
- }
- @Override
- public void unregisterTrustListener(ITrustListener trustListener) throws RemoteException {
- enforceListenerPermission();
- mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget();
- }
- @Override
- public boolean isDeviceLocked(int userId) throws RemoteException {
- userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
- false /* allowAll */, true /* requireFull */, "isDeviceLocked", null);
- long token = Binder.clearCallingIdentity();
- try {
- if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
- userId = resolveProfileParent(userId);
- }
- return isDeviceLockedInner(userId);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- @Override
- public boolean isDeviceSecure(int userId) throws RemoteException {
- userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId,
- false /* allowAll */, true /* requireFull */, "isDeviceSecure", null);
- long token = Binder.clearCallingIdentity();
- try {
- if (!mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
- userId = resolveProfileParent(userId);
- }
- return mLockPatternUtils.isSecure(userId);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- private void enforceReportPermission() {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events");
- }
- private void enforceListenerPermission() {
- mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
- "register trust listener");
- }
- @Override
- protected void dump(FileDescriptor fd, final PrintWriter fout, String[] args) {
- if (!DumpUtils.checkDumpPermission(mContext, TAG, fout)) return;
- if (isSafeMode()) {
- fout.println("disabled because the system is in safe mode.");
- return;
- }
- if (!mTrustAgentsCanRun) {
- fout.println("disabled because the third-party apps can't run yet.");
- return;
- }
- final List<UserInfo> userInfos = mUserManager.getUsers(true /* excludeDying */);
- mHandler.runWithScissors(new Runnable() {
- @Override
- public void run() {
- fout.println("Trust manager state:");
- for (UserInfo user : userInfos) {
- dumpUser(fout, user, user.id == mCurrentUser);
- }
- }
- }, 1500);
- }
- private void dumpUser(PrintWriter fout, UserInfo user, boolean isCurrent) {
- fout.printf(" User \"%s\" (id=%d, flags=%#x)",
- user.name, user.id, user.flags);
- if (!user.supportsSwitchToByUser()) {
- fout.println("(managed profile)");
- fout.println(" disabled because switching to this user is not possible.");
- return;
- }
- if (isCurrent) {
- fout.print(" (current)");
- }
- fout.print(": trusted=" + dumpBool(aggregateIsTrusted(user.id)));
- fout.print(", trustManaged=" + dumpBool(aggregateIsTrustManaged(user.id)));
- fout.print(", deviceLocked=" + dumpBool(isDeviceLockedInner(user.id)));
- fout.print(", strongAuthRequired=" + dumpHex(
- mStrongAuthTracker.getStrongAuthForUser(user.id)));
- fout.println();
- fout.println(" Enabled agents:");
- boolean duplicateSimpleNames = false;
- ArraySet<String> simpleNames = new ArraySet<String>();
- for (AgentInfo info : mActiveAgents) {
- if (info.userId != user.id) { continue; }
- boolean trusted = info.agent.isTrusted();
- fout.print(" "); fout.println(info.component.flattenToShortString());
- fout.print(" bound=" + dumpBool(info.agent.isBound()));
- fout.print(", connected=" + dumpBool(info.agent.isConnected()));
- fout.print(", managingTrust=" + dumpBool(info.agent.isManagingTrust()));
- fout.print(", trusted=" + dumpBool(trusted));
- fout.println();
- if (trusted) {
- fout.println(" message=\"" + info.agent.getMessage() + "\"");
- }
- if (!info.agent.isConnected()) {
- String restartTime = TrustArchive.formatDuration(
- info.agent.getScheduledRestartUptimeMillis()
- - SystemClock.uptimeMillis());
- fout.println(" restartScheduledAt=" + restartTime);
- }
- if (!simpleNames.add(TrustArchive.getSimpleName(info.component))) {
- duplicateSimpleNames = true;
- }
- }
- fout.println(" Events:");
- mArchive.dump(fout, 50, user.id, " " /* linePrefix */, duplicateSimpleNames);
- fout.println();
- }
- private String dumpBool(boolean b) {
- return b ? "1" : "0";
- }
- private String dumpHex(int i) {
- return "0x" + Integer.toHexString(i);
- }
- @Override
- public void setDeviceLockedForUser(int userId, boolean locked) {
- enforceReportPermission();
- final long identity = Binder.clearCallingIdentity();
- try {
- if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) {
- synchronized (mDeviceLockedForUser) {
- mDeviceLockedForUser.put(userId, locked);
- }
- if (locked) {
- try {
- ActivityManager.getService().notifyLockedProfile(userId);
- } catch (RemoteException e) {
- }
- }
- final Intent lockIntent = new Intent(Intent.ACTION_DEVICE_LOCKED_CHANGED);
- lockIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
- lockIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- mContext.sendBroadcastAsUser(lockIntent, UserHandle.SYSTEM,
- Manifest.permission.TRUST_LISTENER, /* options */ null);
- }
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- @Override
- public boolean isTrustUsuallyManaged(int userId) {
- mContext.enforceCallingPermission(Manifest.permission.TRUST_LISTENER,
- "query trust state");
- return isTrustUsuallyManagedInternal(userId);
- }
- @Override
- public void unlockedByFingerprintForUser(int userId) {
- enforceReportPermission();
- synchronized(mUsersUnlockedByFingerprint) {
- mUsersUnlockedByFingerprint.put(userId, true);
- }
- mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, userId,
- 0 /* arg2 */).sendToTarget();
- }
- @Override
- public void clearAllFingerprints() {
- enforceReportPermission();
- synchronized(mUsersUnlockedByFingerprint) {
- mUsersUnlockedByFingerprint.clear();
- }
- mHandler.obtainMessage(MSG_REFRESH_DEVICE_LOCKED_FOR_USER, UserHandle.USER_ALL,
- 0 /* arg2 */).sendToTarget();
- }
- };
- private boolean isTrustUsuallyManagedInternal(int userId) {
- synchronized (mTrustUsuallyManagedForUser) {
- int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
- if (i >= 0) {
- return mTrustUsuallyManagedForUser.valueAt(i);
- }
- }
- // It's not in memory yet, get the value from persisted storage instead
- boolean persistedValue = mLockPatternUtils.isTrustUsuallyManaged(userId);
- synchronized (mTrustUsuallyManagedForUser) {
- int i = mTrustUsuallyManagedForUser.indexOfKey(userId);
- if (i >= 0) {
- // Someone set the trust usually managed in the mean time. Better use that.
- return mTrustUsuallyManagedForUser.valueAt(i);
- } else {
- // .. otherwise it's safe to cache the fetched value now.
- mTrustUsuallyManagedForUser.put(userId, persistedValue);
- return persistedValue;
- }
- }
- }
- private int resolveProfileParent(int userId) {
- long identity = Binder.clearCallingIdentity();
- try {
- UserInfo parent = mUserManager.getProfileParent(userId);
- if (parent != null) {
- return parent.getUserHandle().getIdentifier();
- }
- return userId;
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- private final Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_REGISTER_LISTENER:
- addListener((ITrustListener) msg.obj);
- break;
- case MSG_UNREGISTER_LISTENER:
- removeListener((ITrustListener) msg.obj);
- break;
- case MSG_DISPATCH_UNLOCK_ATTEMPT:
- dispatchUnlockAttempt(msg.arg1 != 0, msg.arg2);
- break;
- case MSG_DISPATCH_UNLOCK_LOCKOUT:
- dispatchUnlockLockout(msg.arg1, msg.arg2);
- break;
- case MSG_ENABLED_AGENTS_CHANGED:
- refreshAgentList(UserHandle.USER_ALL);
- // This is also called when the security mode of a user changes.
- refreshDeviceLockedForUser(UserHandle.USER_ALL);
- break;
- case MSG_KEYGUARD_SHOWING_CHANGED:
- refreshDeviceLockedForUser(mCurrentUser);
- break;
- case MSG_START_USER:
- case MSG_CLEANUP_USER:
- case MSG_UNLOCK_USER:
- refreshAgentList(msg.arg1);
- break;
- case MSG_SWITCH_USER:
- mCurrentUser = msg.arg1;
- refreshDeviceLockedForUser(UserHandle.USER_ALL);
- break;
- case MSG_STOP_USER:
- setDeviceLockedForUser(msg.arg1, true);
- break;
- case MSG_FLUSH_TRUST_USUALLY_MANAGED:
- SparseBooleanArray usuallyManaged;
- synchronized (mTrustUsuallyManagedForUser) {
- usuallyManaged = mTrustUsuallyManagedForUser.clone();
- }
- for (int i = 0; i < usuallyManaged.size(); i++) {
- int userId = usuallyManaged.keyAt(i);
- boolean value = usuallyManaged.valueAt(i);
- if (value != mLockPatternUtils.isTrustUsuallyManaged(userId)) {
- mLockPatternUtils.setTrustUsuallyManaged(value, userId);
- }
- }
- break;
- case MSG_REFRESH_DEVICE_LOCKED_FOR_USER:
- refreshDeviceLockedForUser(msg.arg1);
- break;
- }
- }
- };
- private final PackageMonitor mPackageMonitor = new PackageMonitor() {
- @Override
- public void onSomePackagesChanged() {
- refreshAgentList(UserHandle.USER_ALL);
- }
- @Override
- public boolean onPackageChanged(String packageName, int uid, String[] components) {
- // We're interested in all changes, even if just some components get enabled / disabled.
- return true;
- }
- @Override
- public void onPackageDisappeared(String packageName, int reason) {
- removeAgentsOfPackage(packageName);
- }
- };
- 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
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(action)) {
- refreshAgentList(getSendingUserId());
- updateDevicePolicyFeatures();
- } else if (Intent.ACTION_USER_ADDED.equals(action)) {
- int userId = getUserId(intent);
- if (userId > 0) {
- maybeEnableFactoryTrustAgents(mLockPatternUtils, userId);
- }
- } else if (Intent.ACTION_USER_REMOVED.equals(action)) {
- int userId = getUserId(intent);
- if (userId > 0) {
- synchronized (mUserIsTrusted) {
- mUserIsTrusted.delete(userId);
- }
- synchronized (mDeviceLockedForUser) {
- mDeviceLockedForUser.delete(userId);
- }
- synchronized (mTrustUsuallyManagedForUser) {
- mTrustUsuallyManagedForUser.delete(userId);
- }
- synchronized (mUsersUnlockedByFingerprint) {
- mUsersUnlockedByFingerprint.delete(userId);
- }
- refreshAgentList(userId);
- refreshDeviceLockedForUser(userId);
- }
- }
- }
- private int getUserId(Intent intent) {
- int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -100);
- if (userId > 0) {
- return userId;
- } else {
- Slog.wtf(TAG, "EXTRA_USER_HANDLE missing or invalid, value=" + userId);
- return -100;
- }
- }
- public void register(Context context) {
- IntentFilter filter = new IntentFilter();
- filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
- filter.addAction(Intent.ACTION_USER_ADDED);
- filter.addAction(Intent.ACTION_USER_REMOVED);
- context.registerReceiverAsUser(this,
- UserHandle.ALL,
- filter,
- null /* permission */,
- null /* scheduler */);
- }
- }
- private class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
- SparseBooleanArray mStartFromSuccessfulUnlock = new SparseBooleanArray();
- public StrongAuthTracker(Context context) {
- super(context);
- }
- @Override
- public void onStrongAuthRequiredChanged(int userId) {
- mStartFromSuccessfulUnlock.delete(userId);
- if (DEBUG) {
- Log.i(TAG, "onStrongAuthRequiredChanged(" + userId + ") ->"
- + " trustAllowed=" + isTrustAllowedForUser(userId)
- + " agentsCanRun=" + canAgentsRunForUser(userId));
- }
- refreshAgentList(userId);
- // The list of active trust agents may not have changed, if there was a previous call
- // to allowTrustFromUnlock, so we update the trust here too.
- updateTrust(userId, 0 /* flags */);
- }
- boolean canAgentsRunForUser(int userId) {
- return mStartFromSuccessfulUnlock.get(userId)
- || super.isTrustAllowedForUser(userId);
- }
- /**
- * Temporarily suppress strong auth requirements for {@param userId} until strong auth
- * changes again. Must only be called when we know about a successful unlock already
- * before the underlying StrongAuthTracker.
- *
- * Note that this only changes whether trust agents can be started, not the actual trusted
- * value.
- */
- void allowTrustFromUnlock(int userId) {
- if (userId < UserHandle.USER_SYSTEM) {
- throw new IllegalArgumentException("userId must be a valid user: " + userId);
- }
- boolean previous = canAgentsRunForUser(userId);
- mStartFromSuccessfulUnlock.put(userId, true);
- if (DEBUG) {
- Log.i(TAG, "allowTrustFromUnlock(" + userId + ") ->"
- + " trustAllowed=" + isTrustAllowedForUser(userId)
- + " agentsCanRun=" + canAgentsRunForUser(userId));
- }
- if (canAgentsRunForUser(userId) != previous) {
- refreshAgentList(userId);
- }
- }
- }
- }
TrustManagerService.java的更多相关文章
- Spark案例分析
一.需求:计算网页访问量前三名 import org.apache.spark.rdd.RDD import org.apache.spark.{SparkConf, SparkContext} /* ...
- 故障重现(内存篇2),JAVA内存不足导致频繁回收和swap引起的性能问题
背景起因: 记起以前的另一次也是关于内存的调优分享下 有个系统平时运行非常稳定运行(没经历过大并发考验),然而在一次活动后,人数并发一上来后,系统开始卡. 我按经验开始调优,在每个关键步骤的加入如 ...
- Elasticsearch之java的基本操作一
摘要 接触ElasticSearch已经有一段了.在这期间,遇到很多问题,但在最后自己的不断探索下解决了这些问题.看到网上或多或少的都有一些介绍ElasticSearch相关知识的文档,但个人觉得 ...
- 论:开发者信仰之“天下IT是一家“(Java .NET篇)
比尔盖茨公认的IT界领军人物,打造了辉煌一时的PC时代. 2008年,史蒂夫鲍尔默接替了盖茨的工作,成为微软公司的总裁. 2013年他与微软做了最后的道别. 2013年以后,我才真正看到了微软的变化. ...
- 故障重现, JAVA进程内存不够时突然挂掉模拟
背景,服务器上的一个JAVA服务进程突然挂掉,查看产生了崩溃日志,如下: # Set larger code cache with -XX:ReservedCodeCacheSize= # This ...
- 死磕内存篇 --- JAVA进程和linux内存间的大小关系
运行个JAVA 用sleep去hold住 package org.hjb.test; public class TestOnly { public static void main(String[] ...
- 【小程序分享篇 一 】开发了个JAVA小程序, 用于清除内存卡或者U盘里的垃圾文件非常有用
有一种场景, 手机内存卡空间被用光了,但又不知道哪个文件占用了太大,一个个文件夹去找又太麻烦,所以我开发了个小程序把手机所有文件(包括路径下所有层次子文件夹下的文件)进行一个排序,这样你就可以找出哪个 ...
- Java多线程基础学习(二)
9. 线程安全/共享变量——同步 当多个线程用到同一个变量时,在修改值时存在同时修改的可能性,而此时该变量只能被赋值一次.这就会导致出现“线程安全”问题,这个被多个线程共用的变量称之为“共享变量”. ...
- Java多线程基础学习(一)
1. 创建线程 1.1 通过构造函数:public Thread(Runnable target, String name){} 或:public Thread(Runnable target ...
随机推荐
- var that = this 小坑记
在js编码过程中,经常会使用如上的语句来规避拿不到变量的问题. 比如: queryData:function () { var that=this; var param={}; for(var key ...
- 浅谈C中操作字符串函数的用法(一)
按照内核string.h中函数的顺序进行大概的介绍,若干函数会给出一个简单的例子.有不足之处还希望各位看到的留言告知. 一.memcpy: 函数原型:extern void * memcpy(void ...
- 分析Linux内核5.0系统调用处理过程
学号: 363 本实验来源 https://github.com/mengning/linuxkernel/ 一.实验要求 1.编译内核5.02.qemu -kernel linux-5.0.1/ar ...
- learning makefile string example
- 封装一个redis操作类来操作hash格式
最近项目要用redis,依然是基于tp3.2. 发现thinkphp3.2自带的缓存类并不好使用,就自己封装了一个 目前只支持hash格式,其他数据类型的操作后面用到的时候再补充 <?php / ...
- 保存cookie状态封装
from urllib import request, parsefrom urllib.error import HTTPError,URLError#保存cookiefrom http impor ...
- 解决Charles https抓包显示<unknown>
用mac电脑开发安卓的都应该知道青花瓷吧~(不知道的都是小菜鸡,邪恶.jpg) Charles类似Windows版的Fiddler(没用过Fiddler的都是小菜鸡中的战斗机,嘲笑.png),基本用法 ...
- python机器可读数据-csv
逗号分隔值(Comma-Separated Values,CSV) 1 csv数据 还有一种数据类型,叫制表分隔值(tab-separated values,TSV)数据,有时与CSV归为一类. 若文 ...
- python中的内置函数getattr()介绍及示例
在python的官方文档中:getattr()的解释如下: ? 1 2 3 getattr(object, name[, default]) Return the value of the nam ...
- Sql Server 获取存储过程或函数创建语句
通过该语句可以获取到sqlserver 所有的函数名或者存储过程名 SELECT name FROM sysobjects WHERE xtype='P'; 通过该语句可查询出函数或者存储过的的创建语 ...