下面列出了怎么用android.util.ArraySet的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* Adjusts the wallpaper windows if the input display has a pending wallpaper layout or one of
* the opening apps should be a wallpaper target.
*/
void adjustWallpaperWindowsForAppTransitionIfNeeded(DisplayContent dc,
ArraySet<AppWindowToken> openingApps) {
boolean adjust = false;
if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
adjust = true;
} else {
for (int i = openingApps.size() - 1; i >= 0; --i) {
final AppWindowToken token = openingApps.valueAt(i);
if (token.windowsCanBeWallpaperTarget()) {
adjust = true;
break;
}
}
}
if (adjust) {
adjustWallpaperWindows(dc);
}
}
@Override
void write() {
final ArraySet<Integer> newPersistedTaskIds;
synchronized (mLock) {
newPersistedTaskIds = new ArraySet<>(mPersistedTaskIdsSinceLastRemoveObsolete);
}
for (int userId : mRunningUserIds) {
final File dir = getDirectory(userId);
final String[] files = dir.list();
if (files == null) {
continue;
}
for (String file : files) {
final int taskId = getTaskId(file);
if (!mPersistentTaskIds.contains(taskId)
&& !newPersistedTaskIds.contains(taskId)) {
new File(dir, file).delete();
}
}
}
}
/**
* Register a listener to when this pendingIntent is cancelled. There are no guarantees on which
* thread a listener will be called and it's up to the caller to synchronize. This may
* trigger a synchronous binder call so should therefore usually be called on a background
* thread.
*
* @hide
*/
public void registerCancelListener(CancelListener cancelListener) {
synchronized (this) {
if (mCancelReceiver == null) {
mCancelReceiver = new IResultReceiver.Stub() {
@Override
public void send(int resultCode, Bundle resultData) throws RemoteException {
notifyCancelListeners();
}
};
}
if (mCancelListeners == null) {
mCancelListeners = new ArraySet<>();
}
boolean wasEmpty = mCancelListeners.isEmpty();
mCancelListeners.add(cancelListener);
if (wasEmpty) {
try {
ActivityManager.getService().registerIntentSenderCancelListener(mTarget,
mCancelReceiver);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
}
}
/**
* @return The window token that determines the animation theme.
*/
private AppWindowToken findAnimLayoutParamsToken(@TransitionType int transit,
ArraySet<Integer> activityTypes) {
AppWindowToken result;
// Remote animations always win, but fullscreen tokens override non-fullscreen tokens.
result = lookForHighestTokenWithFilter(mService.mClosingApps, mService.mOpeningApps,
w -> w.getRemoteAnimationDefinition() != null
&& w.getRemoteAnimationDefinition().hasTransition(transit, activityTypes));
if (result != null) {
return result;
}
result = lookForHighestTokenWithFilter(mService.mClosingApps, mService.mOpeningApps,
w -> w.fillsParent() && w.findMainWindow() != null);
if (result != null) {
return result;
}
return lookForHighestTokenWithFilter(mService.mClosingApps, mService.mOpeningApps,
w -> w.findMainWindow() != null);
}
/**
* Determine if a package is signed by the given KeySet.
*
* Returns false if the package was not signed by all the
* keys in the KeySet.
*
* Returns true if the package was signed by at least the
* keys in the given KeySet.
*
* Note that this can return true for multiple KeySets.
*/
public boolean packageIsSignedByLPr(String packageName, KeySetHandle ks) {
PackageSetting pkg = mPackages.get(packageName);
if (pkg == null) {
throw new NullPointerException("Invalid package name");
}
if (pkg.keySetData == null) {
throw new NullPointerException("Package has no KeySet data");
}
long id = getIdByKeySetLPr(ks);
if (id == KEYSET_NOT_FOUND) {
return false;
}
ArraySet<Long> pkgKeys = mKeySetMapping.get(pkg.keySetData.getProperSigningKeySet());
ArraySet<Long> testKeys = mKeySetMapping.get(id);
return pkgKeys.containsAll(testKeys);
}
/**
* Rebuild the sets of allowed components for each current user profile.
*/
public void rebuildAll() {
synchronized (mLock) {
mInstalledSet.clear();
mEnabledSet.clear();
final int[] userIds = getCurrentProfileIds();
for (int i : userIds) {
ArraySet<ComponentName> implementingPackages = loadComponentNamesForUser(i);
ArraySet<ComponentName> packagesFromSettings =
loadComponentNamesFromSetting(mSettingName, i);
packagesFromSettings.retainAll(implementingPackages);
mInstalledSet.put(i, implementingPackages);
mEnabledSet.put(i, packagesFromSettings);
}
}
sendSettingChanged();
}
/**
* Check whether the xml yielded any <include/> tag for the provided <code>domainToken</code>.
* If so, perform a {@link #fullBackupFileTree} which backs up the file or recurses if the path
* is a directory, but only if all the required flags of the include rule are satisfied by
* the transport.
*/
private void applyXmlFiltersAndDoFullBackupForDomain(String packageName, String domainToken,
Map<String, Set<PathWithRequiredFlags>> includeMap,
ArraySet<PathWithRequiredFlags> filterSet, ArraySet<String> traversalExcludeSet,
FullBackupDataOutput data) throws IOException {
if (includeMap == null || includeMap.size() == 0) {
// Do entire sub-tree for the provided token.
fullBackupFileTree(packageName, domainToken,
FullBackup.getBackupScheme(this).tokenToDirectoryPath(domainToken),
filterSet, traversalExcludeSet, data);
} else if (includeMap.get(domainToken) != null) {
// This will be null if the xml parsing didn't yield any rules for
// this domain (there may still be rules for other domains).
for (PathWithRequiredFlags includeFile : includeMap.get(domainToken)) {
if (areIncludeRequiredTransportFlagsSatisfied(includeFile.getRequiredFlags(),
data.getTransportFlags())) {
fullBackupFileTree(packageName, domainToken, includeFile.getPath(), filterSet,
traversalExcludeSet, data);
}
}
}
}
/**
* Informs the system that the given package was signed by the provided KeySet.
*/
void addSigningKeySetToPackageLPw(PackageSetting pkg,
ArraySet<PublicKey> signingKeys) {
/* check existing keyset for reuse or removal */
long signingKeySetId = pkg.keySetData.getProperSigningKeySet();
if (signingKeySetId != PackageKeySetData.KEYSET_UNASSIGNED) {
ArraySet<PublicKey> existingKeys = getPublicKeysFromKeySetLPr(signingKeySetId);
if (existingKeys != null && existingKeys.equals(signingKeys)) {
/* no change in signing keys, leave PackageSetting alone */
return;
} else {
/* old keyset no longer valid, remove ref */
decrementKeySetLPw(signingKeySetId);
}
}
/* create and add a new keyset */
KeySetHandle ks = addKeySetLPw(signingKeys);
long id = ks.getId();
pkg.keySetData.setProperSigningKeySet(id);
return;
}
/**
* Remove dangling bitmap files for a package.
*
* Note this method must be called with the lock held after calling
* {@link ShortcutBitmapSaver#waitForAllSavesLocked()} to make sure there's no pending bitmap
* saves are going on.
*/
private void cleanupDanglingBitmapFilesLocked(@UserIdInt int userId, @NonNull ShortcutUser user,
@NonNull String packageName, @NonNull File path) {
final ArraySet<String> usedFiles =
user.getPackageShortcuts(packageName).getUsedBitmapFiles();
for (File child : path.listFiles()) {
if (!child.isFile()) {
continue;
}
final String name = child.getName();
if (!usedFiles.contains(name)) {
if (DEBUG) {
Slog.d(TAG, "Removing dangling bitmap file: " + child.getAbsolutePath());
}
child.delete();
}
}
}
public void updateServiceConnectionActivitiesLocked(ProcessRecord clientProc) {
ArraySet<ProcessRecord> updatedProcesses = null;
for (int i = 0; i < clientProc.connections.size(); i++) {
final ConnectionRecord conn = clientProc.connections.valueAt(i);
final ProcessRecord proc = conn.binding.service.app;
if (proc == null || proc == clientProc) {
continue;
} else if (updatedProcesses == null) {
updatedProcesses = new ArraySet<>();
} else if (updatedProcesses.contains(proc)) {
continue;
}
updatedProcesses.add(proc);
updateServiceClientActivitiesLocked(proc, null, false);
}
}
/**
* @return the list of persistable task ids.
*/
void getPersistableTaskIds(ArraySet<Integer> persistentTaskIds) {
final int size = mTasks.size();
for (int i = 0; i < size; i++) {
final TaskRecord task = mTasks.get(i);
if (TaskPersister.DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task
+ " persistable=" + task.isPersistable);
final ActivityStack stack = task.getStack();
if ((task.isPersistable || task.inRecents)
&& (stack == null || !stack.isHomeOrRecentsStack())) {
if (TaskPersister.DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task);
persistentTaskIds.add(task.taskId);
} else {
if (TaskPersister.DEBUG) Slog.d(TAG, "omitting from persistentTaskIds task="
+ task);
}
}
}
public void systemReady() {
mAppOps = mContext.getSystemService(AppOpsManager.class);
synchronized (mSessions) {
readSessionsLocked();
reconcileStagesLocked(StorageManager.UUID_PRIVATE_INTERNAL, false /*isInstant*/);
reconcileStagesLocked(StorageManager.UUID_PRIVATE_INTERNAL, true /*isInstant*/);
final ArraySet<File> unclaimedIcons = newArraySet(
mSessionsDir.listFiles());
// Ignore stages and icons claimed by active sessions
for (int i = 0; i < mSessions.size(); i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
unclaimedIcons.remove(buildAppIconFile(session.sessionId));
}
// Clean up orphaned icons
for (File icon : unclaimedIcons) {
Slog.w(TAG, "Deleting orphan icon " + icon);
icon.delete();
}
}
}
/**
* @param arrayList list generated by getConstructorArrayList
* @return new calculation module based on the arrayList parameter
* @throws NameAlreadyRegisteredException when the name is already registered
* @throws NumberOfSeriesExceededLimitException when the number of created modules is exceeded
*/
public static CalculationModule fromConstructorArrayList(ArrayList<String> arrayList) throws NameAlreadyRegisteredException, NumberOfSeriesExceededLimitException {
String name = arrayList.get(0);
boolean valueOfActive = Boolean.parseBoolean(arrayList.get(1));
boolean valueOfLogToFile = Boolean.parseBoolean(arrayList.get(2));
String constellationClassName = arrayList.get(3);
String pvtMethodClassName = arrayList.get(4);
String fileLoggerClassName = arrayList.get(5);
Set<String> correctionClassNames = new ArraySet<>();
for(int i=6; i<arrayList.size(); i++)
correctionClassNames.add(arrayList.get(i));
CalculationModule createdModule = new CalculationModule(
name,
getConstellationClassFromName(constellationClassName),
getCorrectionClassesFromNames(correctionClassNames),
getPvtMethodClassFromName(pvtMethodClassName),
getFileLoggerClassFromName(fileLoggerClassName));
createdModule.active = valueOfActive;
createdModule.logToFile = valueOfLogToFile;
return createdModule;
}
private boolean runIdleOptimization(final JobParameters jobParams,
final PackageManagerService pm, final ArraySet<String> pkgs) {
new Thread("BackgroundDexOptService_IdleOptimization") {
@Override
public void run() {
int result = idleOptimization(pm, pkgs, BackgroundDexOptService.this);
if (result != OPTIMIZE_ABORT_BY_JOB_SCHEDULER) {
Log.w(TAG, "Idle optimizations aborted because of space constraints.");
// If we didn't abort we ran to completion (or stopped because of space).
// Abandon our timeslice and do not reschedule.
jobFinished(jobParams, /* reschedule */ false);
}
}
}.start();
return true;
}
private void scheduleOpActiveChangedIfNeededLocked(int code, int uid, String packageName,
boolean active) {
ArraySet<ActiveCallback> dispatchedCallbacks = null;
final int callbackListCount = mActiveWatchers.size();
for (int i = 0; i < callbackListCount; i++) {
final SparseArray<ActiveCallback> callbacks = mActiveWatchers.valueAt(i);
ActiveCallback callback = callbacks.get(code);
if (callback != null) {
if (callback.mWatchingUid >= 0 && callback.mWatchingUid != uid) {
continue;
}
if (dispatchedCallbacks == null) {
dispatchedCallbacks = new ArraySet<>();
}
dispatchedCallbacks.add(callback);
}
}
if (dispatchedCallbacks == null) {
return;
}
mHandler.sendMessage(PooledLambda.obtainMessage(
AppOpsService::notifyOpActiveChanged,
this, dispatchedCallbacks, code, uid, packageName, active));
}
public PackageUserState(PackageUserState o) {
installed = o.installed;
stopped = o.stopped;
notLaunched = o.notLaunched;
enabled = o.enabled;
hidden = o.hidden;
lastDisableAppCaller = o.lastDisableAppCaller;
disabledComponents = o.disabledComponents != null
? new ArraySet<String>(o.disabledComponents) : null;
enabledComponents = o.enabledComponents != null
? new ArraySet<String>(o.enabledComponents) : null;
blockUninstall = o.blockUninstall;
}
@Override
public @NonNull Set<String> getWhitelistedRestrictedPermissions(
@NonNull String packageName, @PermissionWhitelistFlags int whitelistFlags) {
try {
final List<String> whitelist = mPM.getWhitelistedRestrictedPermissions(
packageName, whitelistFlags, getUserId());
if (whitelist != null) {
return new ArraySet<>(whitelist);
}
return Collections.emptySet();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
@Override
public void setAudioRestriction(int code, int usage, int uid, int mode,
String[] exceptionPackages) {
enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
verifyIncomingUid(uid);
verifyIncomingOp(code);
synchronized (this) {
SparseArray<Restriction> usageRestrictions = mAudioRestrictions.get(code);
if (usageRestrictions == null) {
usageRestrictions = new SparseArray<Restriction>();
mAudioRestrictions.put(code, usageRestrictions);
}
usageRestrictions.remove(usage);
if (mode != AppOpsManager.MODE_ALLOWED) {
final Restriction r = new Restriction();
r.mode = mode;
if (exceptionPackages != null) {
final int N = exceptionPackages.length;
r.exceptionPackages = new ArraySet<String>(N);
for (int i = 0; i < N; i++) {
final String pkg = exceptionPackages[i];
if (pkg != null) {
r.exceptionPackages.add(pkg.trim());
}
}
}
usageRestrictions.put(usage, r);
}
}
mHandler.sendMessage(PooledLambda.obtainMessage(
AppOpsService::notifyWatchersOfChange, this, code, UID_ANY));
}
/**
* @return true if {@param apps} contains an activity in the docked stack, false otherwise.
*/
private boolean containsAppInDockedStack(ArraySet<AppWindowToken> apps) {
for (int i = apps.size() - 1; i >= 0; i--) {
final AppWindowToken token = apps.valueAt(i);
if (token.getTask() != null && token.inSplitScreenPrimaryWindowingMode()) {
return true;
}
}
return false;
}
/**
* Additionally pin a shortcut. c.f. {@link #pinShortcuts(int, String, List, boolean)}
*/
public void addPinnedShortcut(@NonNull String packageName, @UserIdInt int packageUserId,
String id, boolean forPinRequest) {
final ArraySet<String> pinnedSet = getPinnedShortcutIds(packageName, packageUserId);
final ArrayList<String> pinnedList;
if (pinnedSet != null) {
pinnedList = new ArrayList<>(pinnedSet.size() + 1);
pinnedList.addAll(pinnedSet);
} else {
pinnedList = new ArrayList<>(1);
}
pinnedList.add(id);
pinShortcuts(packageUserId, packageName, pinnedList, forPinRequest);
}
public void evaluateConfig(ZenModeConfig config, ComponentName trigger,
boolean processSubscriptions) {
if (config == null) return;
if (config.manualRule != null && config.manualRule.condition != null
&& !config.manualRule.isTrueOrUnknown()) {
if (DEBUG) Log.d(TAG, "evaluateConfig: clearing manual rule");
config.manualRule = null;
}
final ArraySet<Uri> current = new ArraySet<>();
evaluateRule(config.manualRule, current, null, processSubscriptions);
for (ZenRule automaticRule : config.automaticRules.values()) {
evaluateRule(automaticRule, current, trigger, processSubscriptions);
updateSnoozing(automaticRule);
}
synchronized (mSubscriptions) {
final int N = mSubscriptions.size();
for (int i = N - 1; i >= 0; i--) {
final Uri id = mSubscriptions.keyAt(i);
final ComponentName component = mSubscriptions.valueAt(i);
if (processSubscriptions) {
if (!current.contains(id)) {
mConditionProviders.unsubscribeIfNecessary(component, id);
mSubscriptions.removeAt(i);
}
}
}
}
mFirstEvaluation = false;
}
/**
* Convenience method to set the UIDs this network applies to to a single UID.
* @hide
*/
public NetworkCapabilities setSingleUid(int uid) {
final ArraySet<UidRange> identity = new ArraySet<>(1);
identity.add(new UidRange(uid, uid));
setUids(identity);
return this;
}
/**
* @return The set of {@link WindowConfiguration.ActivityType}s contained in the set of apps in
* {@code array1} and {@code array2}.
*/
private ArraySet<Integer> collectActivityTypes(ArraySet<AppWindowToken> array1,
ArraySet<AppWindowToken> array2) {
final ArraySet<Integer> result = new ArraySet<>();
for (int i = array1.size() - 1; i >= 0; i--) {
result.add(array1.valueAt(i).getActivityType());
}
for (int i = array2.size() - 1; i >= 0; i--) {
result.add(array2.valueAt(i).getActivityType());
}
return result;
}
public Set<TrustAnchor> getTrustAnchors() {
// TODO: cache this [but handle mutable sources]
Set<TrustAnchor> anchors = new ArraySet<TrustAnchor>();
for (X509Certificate cert : mSource.getCertificates()) {
anchors.add(new TrustAnchor(cert, mOverridesPins));
}
return anchors;
}
@Override
public Set<X509Certificate> findAllByIssuerAndSignature(X509Certificate cert) {
ensureInitialized();
Set<java.security.cert.TrustAnchor> anchors = mIndex.findAllByIssuerAndSignature(cert);
if (anchors.isEmpty()) {
return Collections.<X509Certificate>emptySet();
}
Set<X509Certificate> certs = new ArraySet<X509Certificate>(anchors.size());
for (java.security.cert.TrustAnchor anchor : anchors) {
certs.add(anchor.getTrustedCert());
}
return certs;
}
/**
* Shows or hides 'app op in use' icons based on app usage.
*/
public void showAppOpsIcons(ArraySet<Integer> appOps) {
if (mOverlayIcon == null || mCameraIcon == null || mMicIcon == null || appOps == null) {
return;
}
mOverlayIcon.setVisibility(appOps.contains(AppOpsManager.OP_SYSTEM_ALERT_WINDOW)
? View.VISIBLE : View.GONE);
mCameraIcon.setVisibility(appOps.contains(AppOpsManager.OP_CAMERA)
? View.VISIBLE : View.GONE);
mMicIcon.setVisibility(appOps.contains(AppOpsManager.OP_RECORD_AUDIO)
? View.VISIBLE : View.GONE);
}
/**
* Any fragments that were removed because they have been postponed should have their views
* made invisible by setting their transition alpha to 0.
*
* @param fragments The fragments that were added during operation execution. Only the ones
* that are no longer added will have their transition alpha changed.
*/
private void makeRemovedFragmentsInvisible(ArraySet<Fragment> fragments) {
final int numAdded = fragments.size();
for (int i = 0; i < numAdded; i++) {
final Fragment fragment = fragments.valueAt(i);
if (!fragment.mAdded) {
final View view = fragment.getView();
view.setTransitionAlpha(0f);
}
}
}
/**
* Note the presence of a {@link Uri} that should have permission granted to
* whoever will be rendering it.
* <p>
* If the enqueuing app has the ability to grant access, it will be added to
* {@link #mGrantableUris}. Otherwise, this will either log or throw
* {@link SecurityException} depending on target SDK of enqueuing app.
*/
private void visitGrantableUri(Uri uri, boolean userOverriddenUri) {
if (uri == null || !ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) return;
// We can't grant Uri permissions from system
final int sourceUid = sbn.getUid();
if (sourceUid == android.os.Process.SYSTEM_UID) return;
final long ident = Binder.clearCallingIdentity();
try {
// This will throw SecurityException if caller can't grant
mAm.checkGrantUriPermission(sourceUid, null,
ContentProvider.getUriWithoutUserId(uri),
Intent.FLAG_GRANT_READ_URI_PERMISSION,
ContentProvider.getUserIdFromUri(uri, UserHandle.getUserId(sourceUid)));
if (mGrantableUris == null) {
mGrantableUris = new ArraySet<>();
}
mGrantableUris.add(uri);
} catch (RemoteException ignored) {
// Ignored because we're in same process
} catch (SecurityException e) {
if (!userOverriddenUri) {
if (mTargetSdkVersion >= Build.VERSION_CODES.P) {
throw e;
} else {
Log.w(TAG, "Ignoring " + uri + " from " + sourceUid + ": " + e.getMessage());
}
}
} finally {
Binder.restoreCallingIdentity(ident);
}
}
/**
* @deprecated TO BE REMOVED.
* @removed
*/
@Deprecated
@Nullable
public Slice bindSlice(@NonNull Intent intent,
@NonNull List<SliceSpec> supportedSpecs) {
return bindSlice(intent, new ArraySet<>(supportedSpecs));
}
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);
}