use of com.android.internal.annotations.VisibleForTesting in project android_frameworks_base by DirtyUnicorns.
the class NotificationManagerService method buzzBeepBlinkLocked.
@VisibleForTesting
void buzzBeepBlinkLocked(NotificationRecord record) {
boolean buzz = false;
boolean beep = false;
boolean blink = false;
final Notification notification = record.sbn.getNotification();
final String key = record.getKey();
final String pkg = record.sbn.getPackageName();
// Should this notification make noise, vibe, or use the LED?
final boolean aboveThreshold = record.getImportance() >= IMPORTANCE_DEFAULT;
final boolean canInterrupt = aboveThreshold && !record.isIntercepted();
if (DBG || record.isIntercepted())
Slog.v(TAG, "pkg=" + pkg + " canInterrupt=" + canInterrupt + " intercept=" + record.isIntercepted());
final int currentUser;
final long token = Binder.clearCallingIdentity();
try {
currentUser = ActivityManager.getCurrentUser();
} finally {
Binder.restoreCallingIdentity(token);
}
// If we're not supposed to beep, vibrate, etc. then don't.
final String disableEffects = disableNotificationEffects(record);
if (disableEffects != null) {
ZenLog.traceDisableEffects(record, disableEffects);
}
// Remember if this notification already owns the notification channels.
boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
boolean wasBuzz = key != null && key.equals(mVibrateNotificationKey);
// These are set inside the conditional if the notification is allowed to make noise.
boolean hasValidVibrate = false;
boolean hasValidSound = false;
if (disableEffects == null && (record.getUserId() == UserHandle.USER_ALL || record.getUserId() == currentUser || mUserProfiles.isCurrentProfile(record.getUserId())) && canInterrupt && mSystemReady && !notificationIsAnnoying(pkg) && mAudioManager != null) {
if (DBG)
Slog.v(TAG, "Interrupting!");
// should we use the default notification sound? (indicated either by
// DEFAULT_SOUND or because notification.sound is pointing at
// Settings.System.NOTIFICATION_SOUND)
final boolean useDefaultSound = (notification.defaults & Notification.DEFAULT_SOUND) != 0 || Settings.System.DEFAULT_NOTIFICATION_URI.equals(notification.sound);
Uri soundUri = null;
if (useDefaultSound) {
soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
// check to see if the default notification sound is silent
hasValidSound = mSystemNotificationSound != null;
} else if (notification.sound != null) {
soundUri = notification.sound;
hasValidSound = (soundUri != null);
}
// Does the notification want to specify its own vibration?
final boolean hasCustomVibrate = notification.vibrate != null;
// new in 4.2: if there was supposed to be a sound and we're in vibrate
// mode, and no other vibration is specified, we fall back to vibration
final boolean convertSoundToVibration = !hasCustomVibrate && hasValidSound && (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE);
// The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
final boolean useDefaultVibrate = (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
hasValidVibrate = useDefaultVibrate || convertSoundToVibration || hasCustomVibrate;
// it once, and we already have, then don't.
if (!(record.isUpdate && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)) {
sendAccessibilityEvent(notification, record.sbn.getPackageName());
if (hasValidSound) {
boolean looping = (notification.flags & Notification.FLAG_INSISTENT) != 0;
AudioAttributes audioAttributes = audioAttributesForNotification(notification);
mSoundNotificationKey = key;
// ringer mode is silent) or if there is a user of exclusive audio focus
if ((mAudioManager.getStreamVolume(AudioAttributes.toLegacyStreamType(audioAttributes)) != 0) && !mAudioManager.isAudioFocusExclusive()) {
final long identity = Binder.clearCallingIdentity();
try {
final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
if (player != null) {
if (DBG)
Slog.v(TAG, "Playing sound " + soundUri + " with attributes " + audioAttributes);
player.playAsync(soundUri, record.sbn.getUser(), looping, audioAttributes);
beep = true;
}
} catch (RemoteException e) {
} finally {
Binder.restoreCallingIdentity(identity);
}
}
}
if (hasValidVibrate && !(mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_SILENT)) {
mVibrateNotificationKey = key;
if (useDefaultVibrate || convertSoundToVibration) {
// Escalate privileges so we can use the vibrator even if the
// notifying app does not have the VIBRATE permission.
long identity = Binder.clearCallingIdentity();
try {
mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), useDefaultVibrate ? mDefaultVibrationPattern : mFallbackVibrationPattern, ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0 : -1, audioAttributesForNotification(notification));
buzz = true;
} finally {
Binder.restoreCallingIdentity(identity);
}
} else if (notification.vibrate.length > 1) {
// If you want your own vibration pattern, you need the VIBRATE
// permission
mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(), notification.vibrate, ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0 : -1, audioAttributesForNotification(notification));
buzz = true;
}
}
}
}
// cancel that feedback now
if (wasBeep && !hasValidSound) {
clearSoundLocked();
}
if (wasBuzz && !hasValidVibrate) {
clearVibrateLocked();
}
// light
// release the light
boolean wasShowLights = mLights.remove(key);
final boolean canInterruptWithLight = canInterrupt || isLedNotificationForcedOn(record) || (!canInterrupt && mZenModeHelper.getAreLightsAllowed());
if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && canInterruptWithLight && ((record.getSuppressedVisualEffects() & NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF) == 0)) {
mLights.add(key);
updateLightsLocked();
if (mUseAttentionLight) {
mAttentionLight.pulse();
}
blink = true;
} else if (wasShowLights) {
updateLightsLocked();
}
if (buzz || beep || blink) {
if (((record.getSuppressedVisualEffects() & NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF) != 0)) {
if (DBG)
Slog.v(TAG, "Suppressed SystemUI from triggering screen on");
} else {
EventLogTags.writeNotificationAlert(key, buzz ? 1 : 0, beep ? 1 : 0, blink ? 1 : 0);
mHandler.post(mBuzzBeepBlinked);
}
}
}
use of com.android.internal.annotations.VisibleForTesting in project android_frameworks_base by DirtyUnicorns.
the class TaskPersister method writePersistedTaskIdsForUser.
@VisibleForTesting
void writePersistedTaskIdsForUser(@NonNull SparseBooleanArray taskIds, int userId) {
if (userId < 0) {
return;
}
final File persistedTaskIdsFile = getUserPersistedTaskIdsFile(userId);
synchronized (mIoLock) {
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new FileWriter(persistedTaskIdsFile));
for (int i = 0; i < taskIds.size(); i++) {
if (taskIds.valueAt(i)) {
writer.write(String.valueOf(taskIds.keyAt(i)));
writer.newLine();
}
}
} catch (Exception e) {
Slog.e(TAG, "Error while writing taskIds file for user " + userId, e);
} finally {
IoUtils.closeQuietly(writer);
}
}
}
use of com.android.internal.annotations.VisibleForTesting in project android_frameworks_base by DirtyUnicorns.
the class Vpn method createUserAndRestrictedProfilesRanges.
/**
* Creates a {@link Set} of non-intersecting {@link UidRange} objects including all UIDs
* associated with one user, and any restricted profiles attached to that user.
*
* <p>If one of {@param allowedApplications} or {@param disallowedApplications} is provided,
* the UID ranges will match the app whitelist or blacklist specified there. Otherwise, all UIDs
* in each user and profile will be included.
*
* @param userHandle The userId to create UID ranges for along with any of its restricted
* profiles.
* @param allowedApplications (optional) whitelist of applications to include.
* @param disallowedApplications (optional) blacklist of applications to exclude.
*/
@VisibleForTesting
Set<UidRange> createUserAndRestrictedProfilesRanges(@UserIdInt int userHandle, @Nullable List<String> allowedApplications, @Nullable List<String> disallowedApplications) {
final Set<UidRange> ranges = new ArraySet<>();
// Assign the top-level user to the set of ranges
addUserToRanges(ranges, userHandle, allowedApplications, disallowedApplications);
// If the user can have restricted profiles, assign all its restricted profiles too
if (canHaveRestrictedProfile(userHandle)) {
final long token = Binder.clearCallingIdentity();
List<UserInfo> users;
try {
users = UserManager.get(mContext).getUsers(true);
} finally {
Binder.restoreCallingIdentity(token);
}
for (UserInfo user : users) {
if (user.isRestricted() && (user.restrictedProfileParentId == userHandle)) {
addUserToRanges(ranges, user.id, allowedApplications, disallowedApplications);
}
}
}
return ranges;
}
use of com.android.internal.annotations.VisibleForTesting in project android_frameworks_base by DirtyUnicorns.
the class AccountManagerService method getPreNDatabaseName.
@VisibleForTesting
String getPreNDatabaseName(int userId) {
File systemDir = Environment.getDataSystemDirectory();
File databaseFile = new File(Environment.getUserSystemDirectory(userId), PRE_N_DATABASE_NAME);
if (userId == 0) {
// Migrate old file, if it exists, to the new location.
// Make sure the new file doesn't already exist. A dummy file could have been
// accidentally created in the old location, causing the new one to become corrupted
// as well.
File oldFile = new File(systemDir, PRE_N_DATABASE_NAME);
if (oldFile.exists() && !databaseFile.exists()) {
// Check for use directory; create if it doesn't exist, else renameTo will fail
File userDir = Environment.getUserSystemDirectory(userId);
if (!userDir.exists()) {
if (!userDir.mkdirs()) {
throw new IllegalStateException("User dir cannot be created: " + userDir);
}
}
if (!oldFile.renameTo(databaseFile)) {
throw new IllegalStateException("User dir cannot be migrated: " + databaseFile);
}
}
}
return databaseFile.getPath();
}
use of com.android.internal.annotations.VisibleForTesting in project android_frameworks_base by ParanoidAndroid.
the class NetworkStatsFactory method javaReadNetworkStatsDetail.
/**
* Parse and return {@link NetworkStats} with UID-level details. Values are
* expected to monotonically increase since device boot.
*/
@VisibleForTesting
public static NetworkStats javaReadNetworkStatsDetail(File detailPath, int limitUid) throws IOException {
final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads();
final NetworkStats stats = new NetworkStats(SystemClock.elapsedRealtime(), 24);
final NetworkStats.Entry entry = new NetworkStats.Entry();
int idx = 1;
int lastIdx = 1;
ProcFileReader reader = null;
try {
// open and consume header line
reader = new ProcFileReader(new FileInputStream(detailPath));
reader.finishLine();
while (reader.hasMoreData()) {
idx = reader.nextInt();
if (idx != lastIdx + 1) {
throw new ProtocolException("inconsistent idx=" + idx + " after lastIdx=" + lastIdx);
}
lastIdx = idx;
entry.iface = reader.nextString();
entry.tag = kernelToTag(reader.nextString());
entry.uid = reader.nextInt();
entry.set = reader.nextInt();
entry.rxBytes = reader.nextLong();
entry.rxPackets = reader.nextLong();
entry.txBytes = reader.nextLong();
entry.txPackets = reader.nextLong();
if (limitUid == UID_ALL || limitUid == entry.uid) {
stats.addValues(entry);
}
reader.finishLine();
}
} catch (NullPointerException e) {
throw new ProtocolException("problem parsing idx " + idx, e);
} catch (NumberFormatException e) {
throw new ProtocolException("problem parsing idx " + idx, e);
} finally {
IoUtils.closeQuietly(reader);
StrictMode.setThreadPolicy(savedPolicy);
}
return stats;
}
Aggregations