Search in sources :

Example 76 with VisibleForTesting

use of com.android.internal.annotations.VisibleForTesting in project platform_frameworks_base by android.

the class RegisteredServicesCache method parseServiceInfo.

@VisibleForTesting
protected ServiceInfo<V> parseServiceInfo(ResolveInfo service) throws XmlPullParserException, IOException {
    android.content.pm.ServiceInfo si = service.serviceInfo;
    ComponentName componentName = new ComponentName(si.packageName, si.name);
    PackageManager pm = mContext.getPackageManager();
    XmlResourceParser parser = null;
    try {
        parser = si.loadXmlMetaData(pm, mMetaDataName);
        if (parser == null) {
            throw new XmlPullParserException("No " + mMetaDataName + " meta-data");
        }
        AttributeSet attrs = Xml.asAttributeSet(parser);
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && type != XmlPullParser.START_TAG) {
        }
        String nodeName = parser.getName();
        if (!mAttributesName.equals(nodeName)) {
            throw new XmlPullParserException("Meta-data does not start with " + mAttributesName + " tag");
        }
        V v = parseServiceAttributes(pm.getResourcesForApplication(si.applicationInfo), si.packageName, attrs);
        if (v == null) {
            return null;
        }
        final android.content.pm.ServiceInfo serviceInfo = service.serviceInfo;
        return new ServiceInfo<V>(v, serviceInfo, componentName);
    } catch (NameNotFoundException e) {
        throw new XmlPullParserException("Unable to load resources for pacakge " + si.packageName);
    } finally {
        if (parser != null)
            parser.close();
    }
}
Also used : XmlResourceParser(android.content.res.XmlResourceParser) NameNotFoundException(android.content.pm.PackageManager.NameNotFoundException) AttributeSet(android.util.AttributeSet) ComponentName(android.content.ComponentName) XmlPullParserException(org.xmlpull.v1.XmlPullParserException) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Example 77 with VisibleForTesting

use of com.android.internal.annotations.VisibleForTesting in project platform_frameworks_base by android.

the class NetworkMonitor method sendHttpProbe.

/**
     * Do a URL fetch on a known web server to see if we get the data we expect.
     * @return a CaptivePortalProbeResult inferred from the HTTP response.
     */
@VisibleForTesting
protected CaptivePortalProbeResult sendHttpProbe(URL url, int probeType) {
    HttpURLConnection urlConnection = null;
    int httpResponseCode = 599;
    String redirectUrl = null;
    final Stopwatch probeTimer = new Stopwatch().start();
    try {
        urlConnection = (HttpURLConnection) mNetworkAgentInfo.network.openConnection(url);
        urlConnection.setInstanceFollowRedirects(probeType == ValidationProbeEvent.PROBE_PAC);
        urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
        urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
        urlConnection.setUseCaches(false);
        final String userAgent = getCaptivePortalUserAgent(mContext);
        if (userAgent != null) {
            urlConnection.setRequestProperty("User-Agent", userAgent);
        }
        // cannot read request header after connection
        String requestHeader = urlConnection.getRequestProperties().toString();
        // Time how long it takes to get a response to our request
        long requestTimestamp = SystemClock.elapsedRealtime();
        httpResponseCode = urlConnection.getResponseCode();
        redirectUrl = urlConnection.getHeaderField("location");
        // Time how long it takes to get a response to our request
        long responseTimestamp = SystemClock.elapsedRealtime();
        validationLog(ValidationProbeEvent.getProbeName(probeType) + " " + url + " time=" + (responseTimestamp - requestTimestamp) + "ms" + " ret=" + httpResponseCode + " request=" + requestHeader + " headers=" + urlConnection.getHeaderFields());
        // proxy server.
        if (httpResponseCode == 200) {
            if (probeType == ValidationProbeEvent.PROBE_PAC) {
                validationLog("PAC fetch 200 response interpreted as 204 response.");
                httpResponseCode = 204;
            } else if (urlConnection.getContentLengthLong() == 0) {
                // Consider 200 response with "Content-length=0" to not be a captive portal.
                // There's no point in considering this a captive portal as the user cannot
                // sign-in to an empty page. Probably the result of a broken transparent proxy.
                // See http://b/9972012.
                validationLog("200 response with Content-length=0 interpreted as 204 response.");
                httpResponseCode = 204;
            } else if (urlConnection.getContentLengthLong() == -1) {
                // response. Do not use available() as it is unreliable. See http://b/33498325.
                if (urlConnection.getInputStream().read() == -1) {
                    validationLog("Empty 200 response interpreted as 204 response.");
                    httpResponseCode = 204;
                }
            }
        }
    } catch (IOException e) {
        validationLog("Probably not a portal: exception " + e);
        if (httpResponseCode == 599) {
        // TODO: Ping gateway and DNS server and log results.
        }
    } finally {
        if (urlConnection != null) {
            urlConnection.disconnect();
        }
    }
    logValidationProbe(probeTimer.stop(), probeType, httpResponseCode);
    return new CaptivePortalProbeResult(httpResponseCode, redirectUrl, url.toString());
}
Also used : HttpURLConnection(java.net.HttpURLConnection) Stopwatch(android.net.util.Stopwatch) IOException(java.io.IOException) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Example 78 with VisibleForTesting

use of com.android.internal.annotations.VisibleForTesting in project platform_frameworks_base by android.

the class NetworkMonitor method isCaptivePortal.

@VisibleForTesting
protected CaptivePortalProbeResult isCaptivePortal() {
    if (!mIsCaptivePortalCheckEnabled) {
        validationLog("Validation disabled.");
        return new CaptivePortalProbeResult(204);
    }
    URL pacUrl = null, httpsUrl = null, httpUrl = null, fallbackUrl = null;
    // On networks with a PAC instead of fetching a URL that should result in a 204
    // response, we instead simply fetch the PAC script.  This is done for a few reasons:
    // 1. At present our PAC code does not yet handle multiple PACs on multiple networks
    //    until something like https://android-review.googlesource.com/#/c/115180/ lands.
    //    Network.openConnection() will ignore network-specific PACs and instead fetch
    //    using NO_PROXY.  If a PAC is in place, the only fetch we know will succeed with
    //    NO_PROXY is the fetch of the PAC itself.
    // 2. To proxy the generate_204 fetch through a PAC would require a number of things
    //    happen before the fetch can commence, namely:
    //        a) the PAC script be fetched
    //        b) a PAC script resolver service be fired up and resolve the captive portal
    //           server.
    //    Network validation could be delayed until these prerequisities are satisifed or
    //    could simply be left to race them.  Neither is an optimal solution.
    // 3. PAC scripts are sometimes used to block or restrict Internet access and may in
    //    fact block fetching of the generate_204 URL which would lead to false negative
    //    results for network validation.
    final ProxyInfo proxyInfo = mNetworkAgentInfo.linkProperties.getHttpProxy();
    if (proxyInfo != null && !Uri.EMPTY.equals(proxyInfo.getPacFileUrl())) {
        pacUrl = makeURL(proxyInfo.getPacFileUrl().toString());
        if (pacUrl == null) {
            return CaptivePortalProbeResult.FAILED;
        }
    }
    if (pacUrl == null) {
        httpsUrl = makeURL(getCaptivePortalServerHttpsUrl(mContext));
        httpUrl = makeURL(getCaptivePortalServerHttpUrl(mContext));
        fallbackUrl = makeURL(getCaptivePortalFallbackUrl(mContext));
        if (httpUrl == null || httpsUrl == null) {
            return CaptivePortalProbeResult.FAILED;
        }
    }
    long startTime = SystemClock.elapsedRealtime();
    final CaptivePortalProbeResult result;
    if (pacUrl != null) {
        result = sendDnsAndHttpProbes(null, pacUrl, ValidationProbeEvent.PROBE_PAC);
    } else if (mUseHttps) {
        result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl, fallbackUrl);
    } else {
        result = sendDnsAndHttpProbes(proxyInfo, httpUrl, ValidationProbeEvent.PROBE_HTTP);
    }
    long endTime = SystemClock.elapsedRealtime();
    sendNetworkConditionsBroadcast(true, /* response received */
    result.isPortal(), /* isCaptivePortal */
    startTime, endTime);
    return result;
}
Also used : ProxyInfo(android.net.ProxyInfo) URL(java.net.URL) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Example 79 with VisibleForTesting

use of com.android.internal.annotations.VisibleForTesting in project platform_frameworks_base by android.

the class NetworkStatsObservers method getHandlerLooperLocked.

@VisibleForTesting
protected Looper getHandlerLooperLocked() {
    HandlerThread handlerThread = new HandlerThread(TAG);
    handlerThread.start();
    return handlerThread.getLooper();
}
Also used : HandlerThread(android.os.HandlerThread) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Example 80 with VisibleForTesting

use of com.android.internal.annotations.VisibleForTesting in project platform_frameworks_base by android.

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();
    // 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=" + record.sbn.getPackageName() + " 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 && 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);
    if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && aboveThreshold && ((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);
        }
    }
}
Also used : AudioAttributes(android.media.AudioAttributes) IRingtonePlayer(android.media.IRingtonePlayer) RemoteException(android.os.RemoteException) Uri(android.net.Uri) ITransientNotification(android.app.ITransientNotification) Notification(android.app.Notification) StatusBarNotification(android.service.notification.StatusBarNotification) VisibleForTesting(com.android.internal.annotations.VisibleForTesting)

Aggregations

VisibleForTesting (com.android.internal.annotations.VisibleForTesting)141 ArrayList (java.util.ArrayList)39 IOException (java.io.IOException)26 XmlPullParserException (org.xmlpull.v1.XmlPullParserException)18 ComponentName (android.content.ComponentName)15 File (java.io.File)14 RemoteException (android.os.RemoteException)13 ArraySet (android.util.ArraySet)10 AtomicFile (android.util.AtomicFile)10 FileInputStream (java.io.FileInputStream)10 Locale (java.util.Locale)10 NameNotFoundException (android.content.pm.PackageManager.NameNotFoundException)9 FileNotFoundException (java.io.FileNotFoundException)9 Notification (android.app.Notification)6 ErrnoException (android.system.ErrnoException)6 FastXmlSerializer (com.android.internal.util.FastXmlSerializer)6 FileOutputStream (java.io.FileOutputStream)6 XmlSerializer (org.xmlpull.v1.XmlSerializer)6 ITransientNotification (android.app.ITransientNotification)5 UserInfo (android.content.pm.UserInfo)5