@TestTargetNew(
     level = TestLevel.COMPLETE,
     method = "toString",
     args = {})
 public void testToString() {
   mNotification = new Notification();
   assertNotNull(mNotification.toString());
 }
  public void enqueueNotificationInternal(
      String pkg,
      int callingUid,
      int callingPid,
      String tag,
      int id,
      int priority,
      Notification notification,
      int[] idOut) {
    checkIncomingCall(pkg);

    // Limit the number of notifications that any given package except the android
    // package can enqueue.  Prevents DOS attacks and deals with leaks.
    if (!"android".equals(pkg)) {
      synchronized (mNotificationList) {
        int count = 0;
        final int N = mNotificationList.size();
        for (int i = 0; i < N; i++) {
          final NotificationRecord r = mNotificationList.get(i);
          if (r.pkg.equals(pkg)) {
            count++;
            if (count >= MAX_PACKAGE_NOTIFICATIONS) {
              Slog.e(
                  TAG,
                  "Package has already posted "
                      + count
                      + " notifications.  Not showing more.  package="
                      + pkg);
              return;
            }
          }
        }
      }
    }

    // This conditional is a dirty hack to limit the logging done on
    //     behalf of the download manager without affecting other apps.
    if (!pkg.equals("com.android.providers.downloads")
        || Log.isLoggable("DownloadManager", Log.VERBOSE)) {
      EventLog.writeEvent(EventLogTags.NOTIFICATION_ENQUEUE, pkg, id, notification.toString());
    }

    if (pkg == null || notification == null) {
      throw new IllegalArgumentException(
          "null not allowed: pkg=" + pkg + " id=" + id + " notification=" + notification);
    }
    if (notification.icon != 0) {
      if (notification.contentView == null) {
        throw new IllegalArgumentException(
            "contentView required: pkg=" + pkg + " id=" + id + " notification=" + notification);
      }
    }

    synchronized (mNotificationList) {
      NotificationRecord r =
          new NotificationRecord(pkg, tag, id, callingUid, callingPid, priority, notification);
      NotificationRecord old = null;

      int index = indexOfNotificationLocked(pkg, tag, id);
      if (index < 0) {
        mNotificationList.add(r);
      } else {
        old = mNotificationList.remove(index);
        mNotificationList.add(index, r);
        // Make sure we don't lose the foreground service state.
        if (old != null) {
          notification.flags |= old.notification.flags & Notification.FLAG_FOREGROUND_SERVICE;
        }
      }

      // Ensure if this is a foreground service that the proper additional
      // flags are set.
      if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
        notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
      }

      if (notification.icon != 0) {
        StatusBarNotification n =
            new StatusBarNotification(pkg, id, tag, r.uid, r.initialPid, notification);
        n.priority = r.priority;

        if (old != null && old.statusBarKey != null) {
          r.statusBarKey = old.statusBarKey;
          long identity = Binder.clearCallingIdentity();
          try {
            mStatusBar.updateNotification(r.statusBarKey, n);
          } finally {
            Binder.restoreCallingIdentity(identity);
          }
        } else {
          long identity = Binder.clearCallingIdentity();
          try {
            r.statusBarKey = mStatusBar.addNotification(n);
            mAttentionLight.pulse();
          } finally {
            Binder.restoreCallingIdentity(identity);
          }
        }
        sendAccessibilityEvent(notification, pkg);
      } else {
        Slog.e(TAG, "Ignoring notification with icon==0: " + notification);
        if (old != null && old.statusBarKey != null) {
          long identity = Binder.clearCallingIdentity();
          try {
            mStatusBar.removeNotification(old.statusBarKey);
          } finally {
            Binder.restoreCallingIdentity(identity);
          }
        }
      }

      // If we're not supposed to beep, vibrate, etc. then don't.
      if (((mDisabledNotifications & StatusBarManager.DISABLE_NOTIFICATION_ALERTS) == 0)
          && (!(old != null && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0))
          && mSystemReady) {

        final AudioManager audioManager =
            (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
        // sound
        final boolean useDefaultSound = (notification.defaults & Notification.DEFAULT_SOUND) != 0;
        if (useDefaultSound || notification.sound != null) {
          Uri uri;
          if (useDefaultSound) {
            uri = Settings.System.DEFAULT_NOTIFICATION_URI;
          } else {
            uri = notification.sound;
          }
          boolean looping = (notification.flags & Notification.FLAG_INSISTENT) != 0;
          int audioStreamType;
          if (notification.audioStreamType >= 0) {
            audioStreamType = notification.audioStreamType;
          } else {
            audioStreamType = DEFAULT_STREAM_TYPE;
          }
          mSoundNotification = r;
          // do not play notifications if stream volume is 0
          // (typically because ringer mode is silent).
          if (audioManager.getStreamVolume(audioStreamType) != 0) {
            long identity = Binder.clearCallingIdentity();
            try {
              mSound.play(mContext, uri, looping, audioStreamType);
            } finally {
              Binder.restoreCallingIdentity(identity);
            }
          }
        }

        // vibrate
        final boolean useDefaultVibrate =
            (notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
        if ((useDefaultVibrate || notification.vibrate != null)
            && audioManager.shouldVibrate(AudioManager.VIBRATE_TYPE_NOTIFICATION)) {
          mVibrateNotification = r;

          mVibrator.vibrate(
              useDefaultVibrate ? DEFAULT_VIBRATE_PATTERN : notification.vibrate,
              ((notification.flags & Notification.FLAG_INSISTENT) != 0) ? 0 : -1);
        }
      }

      // this option doesn't shut off the lights

      // light
      // the most recent thing gets the light
      mLights.remove(old);
      if (mLedNotification == old) {
        mLedNotification = null;
      }
      // Slog.i(TAG, "notification.lights="
      //        + ((old.notification.lights.flags & Notification.FLAG_SHOW_LIGHTS) != 0));
      if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0) {
        mLights.add(r);
        updateLightsLocked();
      } else {
        if (old != null && ((old.notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0)) {
          updateLightsLocked();
        }
      }
    }

    idOut[0] = id;
  }