Search in sources :

Example 31 with ProxyInfo

use of android.net.ProxyInfo in project platform_frameworks_base by android.

the class ActivityManagerService method broadcastIntentLocked.

final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
    intent = new Intent(intent);
    // By default broadcasts do not go to stopped apps.
    intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
    // If we have not finished booting, don't allow this to launch new processes.
    if (!mProcessesReady && (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
    }
    if (DEBUG_BROADCAST_LIGHT)
        Slog.v(TAG_BROADCAST, (sticky ? "Broadcast sticky: " : "Broadcast: ") + intent + " ordered=" + ordered + " userid=" + userId);
    if ((resultTo != null) && !ordered) {
        Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
    }
    userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, ALLOW_NON_FULL, "broadcast", callerPackage);
    if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
        if ((callingUid != Process.SYSTEM_UID || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
            Slog.w(TAG, "Skipping broadcast of " + intent + ": user " + userId + " is stopped");
            return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
        }
    }
    BroadcastOptions brOptions = null;
    if (bOptions != null) {
        brOptions = new BroadcastOptions(bOptions);
        if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
            // PendingIntent), because that who is actually supplied the arguments.
            if (checkComponentPermission(android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST, Binder.getCallingPid(), Binder.getCallingUid(), -1, true) != PackageManager.PERMISSION_GRANTED) {
                String msg = "Permission Denial: " + intent.getAction() + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " requires " + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
                Slog.w(TAG, msg);
                throw new SecurityException(msg);
            }
        }
    }
    // Verify that protected broadcasts are only being sent by system code,
    // and that system code is only sending protected broadcasts.
    final String action = intent.getAction();
    final boolean isProtectedBroadcast;
    try {
        isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
    } catch (RemoteException e) {
        Slog.w(TAG, "Remote exception", e);
        return ActivityManager.BROADCAST_SUCCESS;
    }
    final boolean isCallerSystem;
    switch(UserHandle.getAppId(callingUid)) {
        case Process.ROOT_UID:
        case Process.SYSTEM_UID:
        case Process.PHONE_UID:
        case Process.BLUETOOTH_UID:
        case Process.NFC_UID:
            isCallerSystem = true;
            break;
        default:
            isCallerSystem = (callerApp != null) && callerApp.persistent;
            break;
    }
    // sending protected broadcasts.
    if (!isCallerSystem) {
        if (isProtectedBroadcast) {
            String msg = "Permission Denial: not allowed to send broadcast " + action + " from pid=" + callingPid + ", uid=" + callingUid;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action) || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
            // just limit it to the caller.
            if (callerPackage == null) {
                String msg = "Permission Denial: not allowed to send broadcast " + action + " from unknown caller.";
                Slog.w(TAG, msg);
                throw new SecurityException(msg);
            } else if (intent.getComponent() != null) {
                // it is being sent to the calling app.
                if (!intent.getComponent().getPackageName().equals(callerPackage)) {
                    String msg = "Permission Denial: not allowed to send broadcast " + action + " to " + intent.getComponent().getPackageName() + " from " + callerPackage;
                    Slog.w(TAG, msg);
                    throw new SecurityException(msg);
                }
            } else {
                // Limit broadcast to their own package.
                intent.setPackage(callerPackage);
            }
        }
    }
    if (action != null) {
        switch(action) {
            case Intent.ACTION_UID_REMOVED:
            case Intent.ACTION_PACKAGE_REMOVED:
            case Intent.ACTION_PACKAGE_CHANGED:
            case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
            case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
            case Intent.ACTION_PACKAGES_SUSPENDED:
            case Intent.ACTION_PACKAGES_UNSUSPENDED:
                // its activities from the history stack.
                if (checkComponentPermission(android.Manifest.permission.BROADCAST_PACKAGE_REMOVED, callingPid, callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) {
                    String msg = "Permission Denial: " + intent.getAction() + " broadcast from " + callerPackage + " (pid=" + callingPid + ", uid=" + callingUid + ")" + " requires " + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
                    Slog.w(TAG, msg);
                    throw new SecurityException(msg);
                }
                switch(action) {
                    case Intent.ACTION_UID_REMOVED:
                        final Bundle intentExtras = intent.getExtras();
                        final int uid = intentExtras != null ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
                        if (uid >= 0) {
                            mBatteryStatsService.removeUid(uid);
                            mAppOpsService.uidRemoved(uid);
                        }
                        break;
                    case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
                        // If resources are unavailable just force stop all those packages
                        // and flush the attribute cache as well.
                        String[] list = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                        if (list != null && list.length > 0) {
                            for (int i = 0; i < list.length; i++) {
                                forceStopPackageLocked(list[i], -1, false, true, true, false, false, userId, "storage unmount");
                            }
                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
                            sendPackageBroadcastLocked(IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
                        }
                        break;
                    case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
                        mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
                        break;
                    case Intent.ACTION_PACKAGE_REMOVED:
                    case Intent.ACTION_PACKAGE_CHANGED:
                        Uri data = intent.getData();
                        String ssp;
                        if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
                            final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                            final boolean killProcess = !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
                            final boolean fullUninstall = removed && !replacing;
                            if (removed) {
                                if (killProcess) {
                                    forceStopPackageLocked(ssp, UserHandle.getAppId(intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true, false, fullUninstall, userId, removed ? "pkg removed" : "pkg changed");
                                }
                                final int cmd = killProcess ? IApplicationThread.PACKAGE_REMOVED : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
                                sendPackageBroadcastLocked(cmd, new String[] { ssp }, userId);
                                if (fullUninstall) {
                                    mAppOpsService.packageRemoved(intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
                                    // Remove all permissions granted from/to this package
                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
                                    removeTasksByPackageNameLocked(ssp, userId);
                                    // Hide the "unsupported display" dialog if necessary.
                                    if (mUnsupportedDisplaySizeDialog != null && ssp.equals(mUnsupportedDisplaySizeDialog.getPackageName())) {
                                        mUnsupportedDisplaySizeDialog.dismiss();
                                        mUnsupportedDisplaySizeDialog = null;
                                    }
                                    mCompatModePackages.handlePackageUninstalledLocked(ssp);
                                    mBatteryStatsService.notePackageUninstalled(ssp);
                                }
                            } else {
                                if (killProcess) {
                                    killPackageProcessesLocked(ssp, UserHandle.getAppId(intent.getIntExtra(Intent.EXTRA_UID, -1)), userId, ProcessList.INVALID_ADJ, false, true, true, false, "change " + ssp);
                                }
                                cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess, intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
                            }
                        }
                        break;
                    case Intent.ACTION_PACKAGES_SUSPENDED:
                    case Intent.ACTION_PACKAGES_UNSUSPENDED:
                        final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(intent.getAction());
                        final String[] packageNames = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                        final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
                        synchronized (ActivityManagerService.this) {
                            mRecentTasks.onPackagesSuspendedChanged(packageNames, suspended, userHandle);
                        }
                        break;
                }
                break;
            case Intent.ACTION_PACKAGE_REPLACED:
                {
                    final Uri data = intent.getData();
                    final String ssp;
                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                        final ApplicationInfo aInfo = getPackageManagerInternalLocked().getApplicationInfo(ssp, userId);
                        if (aInfo == null) {
                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:" + " ssp=" + ssp + " data=" + data);
                            return ActivityManager.BROADCAST_SUCCESS;
                        }
                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
                        sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED, new String[] { ssp }, userId);
                    }
                    break;
                }
            case Intent.ACTION_PACKAGE_ADDED:
                {
                    // Special case for adding a package: by default turn on compatibility mode.
                    Uri data = intent.getData();
                    String ssp;
                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                        final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
                        try {
                            ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(ssp, 0, 0);
                            mBatteryStatsService.notePackageInstalled(ssp, ai != null ? ai.versionCode : 0);
                        } catch (RemoteException e) {
                        }
                    }
                    break;
                }
            case Intent.ACTION_PACKAGE_DATA_CLEARED:
                {
                    Uri data = intent.getData();
                    String ssp;
                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                        // Hide the "unsupported display" dialog if necessary.
                        if (mUnsupportedDisplaySizeDialog != null && ssp.equals(mUnsupportedDisplaySizeDialog.getPackageName())) {
                            mUnsupportedDisplaySizeDialog.dismiss();
                            mUnsupportedDisplaySizeDialog = null;
                        }
                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
                    }
                    break;
                }
            case Intent.ACTION_TIMEZONE_CHANGED:
                // If this is the time zone changed action, queue up a message that will reset
                // the timezone of all currently running processes. This message will get
                // queued up before the broadcast happens.
                mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
                break;
            case Intent.ACTION_TIME_CHANGED:
                // If the user set the time, let all running processes know.
                final int is24Hour = intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1 : 0;
                mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
                synchronized (stats) {
                    stats.noteCurrentTimeChangedLocked();
                }
                break;
            case Intent.ACTION_CLEAR_DNS_CACHE:
                mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
                break;
            case Proxy.PROXY_CHANGE_ACTION:
                ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
                mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
                break;
            case android.hardware.Camera.ACTION_NEW_PICTURE:
            case android.hardware.Camera.ACTION_NEW_VIDEO:
                // These broadcasts are no longer allowed by the system, since they can
                // cause significant thrashing at a crictical point (using the camera).
                // Apps should use JobScehduler to monitor for media provider changes.
                Slog.w(TAG, action + " no longer allowed; dropping from " + UserHandle.formatUid(callingUid));
                if (resultTo != null) {
                    final BroadcastQueue queue = broadcastQueueForIntent(intent);
                    try {
                        queue.performReceiveLocked(callerApp, resultTo, intent, Activity.RESULT_CANCELED, null, null, false, false, userId);
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Failure [" + queue.mQueueName + "] sending broadcast result of " + intent, e);
                    }
                }
                // Lie; we don't want to crash the app.
                return ActivityManager.BROADCAST_SUCCESS;
        }
    }
    // Add to the sticky list if requested.
    if (sticky) {
        if (checkPermission(android.Manifest.permission.BROADCAST_STICKY, callingPid, callingUid) != PackageManager.PERMISSION_GRANTED) {
            String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid=" + callingPid + ", uid=" + callingUid + " requires " + android.Manifest.permission.BROADCAST_STICKY;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }
        if (requiredPermissions != null && requiredPermissions.length > 0) {
            Slog.w(TAG, "Can't broadcast sticky intent " + intent + " and enforce permissions " + Arrays.toString(requiredPermissions));
            return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
        }
        if (intent.getComponent() != null) {
            throw new SecurityException("Sticky broadcasts can't target a specific component");
        }
        // as a separate set of sticky broadcasts.
        if (userId != UserHandle.USER_ALL) {
            // But first, if this is not a broadcast to all users, then
            // make sure it doesn't conflict with an existing broadcast to
            // all users.
            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(UserHandle.USER_ALL);
            if (stickies != null) {
                ArrayList<Intent> list = stickies.get(intent.getAction());
                if (list != null) {
                    int N = list.size();
                    int i;
                    for (i = 0; i < N; i++) {
                        if (intent.filterEquals(list.get(i))) {
                            throw new IllegalArgumentException("Sticky broadcast " + intent + " for user " + userId + " conflicts with existing global broadcast");
                        }
                    }
                }
            }
        }
        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
        if (stickies == null) {
            stickies = new ArrayMap<>();
            mStickyBroadcasts.put(userId, stickies);
        }
        ArrayList<Intent> list = stickies.get(intent.getAction());
        if (list == null) {
            list = new ArrayList<>();
            stickies.put(intent.getAction(), list);
        }
        final int stickiesCount = list.size();
        int i;
        for (i = 0; i < stickiesCount; i++) {
            if (intent.filterEquals(list.get(i))) {
                // This sticky already exists, replace it.
                list.set(i, new Intent(intent));
                break;
            }
        }
        if (i >= stickiesCount) {
            list.add(new Intent(intent));
        }
    }
    int[] users;
    if (userId == UserHandle.USER_ALL) {
        // Caller wants broadcast to go to all started users.
        users = mUserController.getStartedUserArrayLocked();
    } else {
        // Caller wants broadcast to go to one specific user.
        users = new int[] { userId };
    }
    // Figure out who all will receive this broadcast.
    List receivers = null;
    List<BroadcastFilter> registeredReceivers = null;
    // Need to resolve the intent to interested receivers...
    if ((intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
        receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
    }
    if (intent.getComponent() == null) {
        if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
            // Query one target user at a time, excluding shell-restricted users
            for (int i = 0; i < users.length; i++) {
                if (mUserController.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
                    continue;
                }
                List<BroadcastFilter> registeredReceiversForUser = mReceiverResolver.queryIntent(intent, resolvedType, false, users[i]);
                if (registeredReceivers == null) {
                    registeredReceivers = registeredReceiversForUser;
                } else if (registeredReceiversForUser != null) {
                    registeredReceivers.addAll(registeredReceiversForUser);
                }
            }
        } else {
            registeredReceivers = mReceiverResolver.queryIntent(intent, resolvedType, false, userId);
        }
    }
    final boolean replacePending = (intent.getFlags() & Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
    if (DEBUG_BROADCAST)
        Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction() + " replacePending=" + replacePending);
    int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
    if (!ordered && NR > 0) {
        // components to be launched.
        if (isCallerSystem) {
            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, isProtectedBroadcast, registeredReceivers);
        }
        final BroadcastQueue queue = broadcastQueueForIntent(intent);
        BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, resolvedType, requiredPermissions, appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId);
        if (DEBUG_BROADCAST)
            Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
        final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
        if (!replaced) {
            queue.enqueueParallelBroadcastLocked(r);
            queue.scheduleBroadcastsLocked();
        }
        registeredReceivers = null;
        NR = 0;
    }
    // Merge into one list.
    int ir = 0;
    if (receivers != null) {
        // A special case for PACKAGE_ADDED: do not allow the package
        // being added to see this broadcast.  This prevents them from
        // using this as a back door to get run as soon as they are
        // installed.  Maybe in the future we want to have a special install
        // broadcast or such for apps, but we'd like to deliberately make
        // this decision.
        String[] skipPackages = null;
        if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction()) || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction()) || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
            Uri data = intent.getData();
            if (data != null) {
                String pkgName = data.getSchemeSpecificPart();
                if (pkgName != null) {
                    skipPackages = new String[] { pkgName };
                }
            }
        } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
            skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
        }
        if (skipPackages != null && (skipPackages.length > 0)) {
            for (String skipPackage : skipPackages) {
                if (skipPackage != null) {
                    int NT = receivers.size();
                    for (int it = 0; it < NT; it++) {
                        ResolveInfo curt = (ResolveInfo) receivers.get(it);
                        if (curt.activityInfo.packageName.equals(skipPackage)) {
                            receivers.remove(it);
                            it--;
                            NT--;
                        }
                    }
                }
            }
        }
        int NT = receivers != null ? receivers.size() : 0;
        int it = 0;
        ResolveInfo curt = null;
        BroadcastFilter curr = null;
        while (it < NT && ir < NR) {
            if (curt == null) {
                curt = (ResolveInfo) receivers.get(it);
            }
            if (curr == null) {
                curr = registeredReceivers.get(ir);
            }
            if (curr.getPriority() >= curt.priority) {
                // Insert this broadcast record into the final list.
                receivers.add(it, curr);
                ir++;
                curr = null;
                it++;
                NT++;
            } else {
                // Skip to the next ResolveInfo in the final list.
                it++;
                curt = null;
            }
        }
    }
    while (ir < NR) {
        if (receivers == null) {
            receivers = new ArrayList();
        }
        receivers.add(registeredReceivers.get(ir));
        ir++;
    }
    if (isCallerSystem) {
        checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid, isProtectedBroadcast, receivers);
    }
    if ((receivers != null && receivers.size() > 0) || resultTo != null) {
        BroadcastQueue queue = broadcastQueueForIntent(intent);
        BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, callingPid, callingUid, resolvedType, requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId);
        if (DEBUG_BROADCAST)
            Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r + ": prev had " + queue.mOrderedBroadcasts.size());
        if (DEBUG_BROADCAST)
            Slog.i(TAG_BROADCAST, "Enqueueing broadcast " + r.intent.getAction());
        boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
        if (!replaced) {
            queue.enqueueOrderedBroadcastLocked(r);
            queue.scheduleBroadcastsLocked();
        }
    } else {
        // that it happened.
        if (intent.getComponent() == null && intent.getPackage() == null && (intent.getFlags() & Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
            // This was an implicit broadcast... let's record it for posterity.
            addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
        }
    }
    return ActivityManager.BROADCAST_SUCCESS;
}
Also used : ApplicationInfo(android.content.pm.ApplicationInfo) ArrayList(java.util.ArrayList) Uri(android.net.Uri) ResolveInfo(android.content.pm.ResolveInfo) ProxyInfo(android.net.ProxyInfo) RemoteCallbackList(android.os.RemoteCallbackList) ArrayList(java.util.ArrayList) List(java.util.List) LocaleList(android.os.LocaleList) Bundle(android.os.Bundle) PersistableBundle(android.os.PersistableBundle) PendingIntent(android.app.PendingIntent) Intent(android.content.Intent) BatteryStatsImpl(com.android.internal.os.BatteryStatsImpl) Point(android.graphics.Point) BroadcastOptions(android.app.BroadcastOptions) RemoteException(android.os.RemoteException)

Example 32 with ProxyInfo

use of android.net.ProxyInfo 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 33 with ProxyInfo

use of android.net.ProxyInfo in project platform_frameworks_base by android.

the class PacManager method sendProxyIfNeeded.

private synchronized void sendProxyIfNeeded() {
    if (!mHasDownloaded || (mLastPort == -1)) {
        return;
    }
    if (!mHasSentBroadcast) {
        sendPacBroadcast(new ProxyInfo(mPacUrl, mLastPort));
        mHasSentBroadcast = true;
    }
}
Also used : ProxyInfo(android.net.ProxyInfo)

Example 34 with ProxyInfo

use of android.net.ProxyInfo in project platform_frameworks_base by android.

the class ConnectivityService method handleDeprecatedGlobalHttpProxy.

private void handleDeprecatedGlobalHttpProxy() {
    String proxy = Settings.Global.getString(mContext.getContentResolver(), Settings.Global.HTTP_PROXY);
    if (!TextUtils.isEmpty(proxy)) {
        String[] data = proxy.split(":");
        if (data.length == 0) {
            return;
        }
        String proxyHost = data[0];
        int proxyPort = 8080;
        if (data.length > 1) {
            try {
                proxyPort = Integer.parseInt(data[1]);
            } catch (NumberFormatException e) {
                return;
            }
        }
        ProxyInfo p = new ProxyInfo(data[0], proxyPort, "");
        setGlobalProxy(p);
    }
}
Also used : ProxyInfo(android.net.ProxyInfo) NetworkPolicyManager.uidRulesToString(android.net.NetworkPolicyManager.uidRulesToString)

Example 35 with ProxyInfo

use of android.net.ProxyInfo in project platform_frameworks_base by android.

the class ConnectivityService method updateProxy.

// If the proxy has changed from oldLp to newLp, resend proxy broadcast with default proxy.
// This method gets called when any network changes proxy, but the broadcast only ever contains
// the default proxy (even if it hasn't changed).
// TODO: Deprecate the broadcast extras as they aren't necessarily applicable in a multi-network
// world where an app might be bound to a non-default network.
private void updateProxy(LinkProperties newLp, LinkProperties oldLp, NetworkAgentInfo nai) {
    ProxyInfo newProxyInfo = newLp == null ? null : newLp.getHttpProxy();
    ProxyInfo oldProxyInfo = oldLp == null ? null : oldLp.getHttpProxy();
    if (!proxyInfoEqual(newProxyInfo, oldProxyInfo)) {
        sendProxyBroadcast(getDefaultProxy());
    }
}
Also used : ProxyInfo(android.net.ProxyInfo)

Aggregations

ProxyInfo (android.net.ProxyInfo)66 NetworkPolicyManager.uidRulesToString (android.net.NetworkPolicyManager.uidRulesToString)15 StaticIpConfiguration (android.net.StaticIpConfiguration)11 ContentResolver (android.content.ContentResolver)10 LinkAddress (android.net.LinkAddress)10 IOException (java.io.IOException)10 InetAddress (java.net.InetAddress)10 Intent (android.content.Intent)8 PendingIntent (android.app.PendingIntent)7 ApplicationInfo (android.content.pm.ApplicationInfo)7 RemoteException (android.os.RemoteException)7 ProxySettings (android.net.IpConfiguration.ProxySettings)6 ComponentName (android.content.ComponentName)5 Context (android.content.Context)5 IPackageManager (android.content.pm.IPackageManager)5 InstrumentationInfo (android.content.pm.InstrumentationInfo)5 IpConfiguration (android.net.IpConfiguration)5 IpAssignment (android.net.IpConfiguration.IpAssignment)5 RouteInfo (android.net.RouteInfo)5 SparseArray (android.util.SparseArray)5