am 465e9967: Merge "Consolidated processing of package boardcasts in AM service." into lmp-mr1-dev
* commit '465e996776d916d8d1b62c539142827bd96a42bc': Consolidated processing of package boardcasts in AM service.
This commit is contained in:
@@ -61,7 +61,6 @@ import com.android.internal.app.IAppOpsService;
|
|||||||
import com.android.internal.app.IVoiceInteractor;
|
import com.android.internal.app.IVoiceInteractor;
|
||||||
import com.android.internal.app.ProcessMap;
|
import com.android.internal.app.ProcessMap;
|
||||||
import com.android.internal.app.ProcessStats;
|
import com.android.internal.app.ProcessStats;
|
||||||
import com.android.internal.content.PackageMonitor;
|
|
||||||
import com.android.internal.os.BackgroundThread;
|
import com.android.internal.os.BackgroundThread;
|
||||||
import com.android.internal.os.BatteryStatsImpl;
|
import com.android.internal.os.BatteryStatsImpl;
|
||||||
import com.android.internal.os.ProcessCpuTracker;
|
import com.android.internal.os.ProcessCpuTracker;
|
||||||
@@ -1832,99 +1831,6 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Monitor for package changes and update our internal state.
|
|
||||||
*/
|
|
||||||
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
|
|
||||||
@Override
|
|
||||||
public void onPackageRemoved(String packageName, int uid) {
|
|
||||||
// Remove all tasks with activities in the specified package from the list of recent tasks
|
|
||||||
final int eventUserId = getChangingUserId();
|
|
||||||
synchronized (ActivityManagerService.this) {
|
|
||||||
for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
|
|
||||||
TaskRecord tr = mRecentTasks.get(i);
|
|
||||||
if (tr.userId != eventUserId) continue;
|
|
||||||
|
|
||||||
ComponentName cn = tr.intent.getComponent();
|
|
||||||
if (cn != null && cn.getPackageName().equals(packageName)) {
|
|
||||||
// If the package name matches, remove the task
|
|
||||||
removeTaskByIdLocked(tr.taskId, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onPackageChanged(String packageName, int uid, String[] components) {
|
|
||||||
onPackageModified(packageName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPackageModified(String packageName) {
|
|
||||||
final int eventUserId = getChangingUserId();
|
|
||||||
final IPackageManager pm = AppGlobals.getPackageManager();
|
|
||||||
final ArrayList<Pair<Intent, Integer>> recentTaskIntents =
|
|
||||||
new ArrayList<Pair<Intent, Integer>>();
|
|
||||||
final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
|
|
||||||
final ArrayList<Integer> tasksToRemove = new ArrayList<Integer>();
|
|
||||||
// Copy the list of recent tasks so that we don't hold onto the lock on
|
|
||||||
// ActivityManagerService for long periods while checking if components exist.
|
|
||||||
synchronized (ActivityManagerService.this) {
|
|
||||||
for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
|
|
||||||
TaskRecord tr = mRecentTasks.get(i);
|
|
||||||
if (tr.userId != eventUserId) continue;
|
|
||||||
|
|
||||||
recentTaskIntents.add(new Pair<Intent, Integer>(tr.intent, tr.taskId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Check the recent tasks and filter out all tasks with components that no longer exist.
|
|
||||||
for (int i = recentTaskIntents.size() - 1; i >= 0; i--) {
|
|
||||||
Pair<Intent, Integer> p = recentTaskIntents.get(i);
|
|
||||||
ComponentName cn = p.first.getComponent();
|
|
||||||
if (cn != null && cn.getPackageName().equals(packageName)) {
|
|
||||||
if (componentsKnownToExist.contains(cn)) {
|
|
||||||
// If we know that the component still exists in the package, then skip
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ActivityInfo info = pm.getActivityInfo(cn, 0, eventUserId);
|
|
||||||
if (info != null) {
|
|
||||||
componentsKnownToExist.add(cn);
|
|
||||||
} else {
|
|
||||||
tasksToRemove.add(p.second);
|
|
||||||
}
|
|
||||||
} catch (RemoteException e) {
|
|
||||||
Log.e(TAG, "Failed to query activity info for component: " + cn, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Prune all the tasks with removed components from the list of recent tasks
|
|
||||||
synchronized (ActivityManagerService.this) {
|
|
||||||
for (int i = tasksToRemove.size() - 1; i >= 0; i--) {
|
|
||||||
removeTaskByIdLocked(tasksToRemove.get(i), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onHandleForceStop(Intent intent, String[] packages, int uid, boolean doit) {
|
|
||||||
// Force stop the specified packages
|
|
||||||
int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0);
|
|
||||||
if (packages != null) {
|
|
||||||
for (String pkg : packages) {
|
|
||||||
synchronized (ActivityManagerService.this) {
|
|
||||||
if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
|
|
||||||
userId, "finished booting")) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public void setSystemProcess() {
|
public void setSystemProcess() {
|
||||||
try {
|
try {
|
||||||
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
|
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
|
||||||
@@ -6172,8 +6078,26 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Register receivers to handle package update events
|
IntentFilter pkgFilter = new IntentFilter();
|
||||||
mPackageMonitor.register(mContext, Looper.getMainLooper(), UserHandle.ALL, false);
|
pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
|
||||||
|
pkgFilter.addDataScheme("package");
|
||||||
|
mContext.registerReceiver(new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
|
||||||
|
if (pkgs != null) {
|
||||||
|
for (String pkg : pkgs) {
|
||||||
|
synchronized (ActivityManagerService.this) {
|
||||||
|
if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
|
||||||
|
0, "finished booting")) {
|
||||||
|
setResultCode(Activity.RESULT_OK);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, pkgFilter);
|
||||||
|
|
||||||
// Let system services know.
|
// Let system services know.
|
||||||
mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
|
mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
|
||||||
@@ -8407,6 +8331,47 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void removeTasksByPackageNameLocked(String packageName, int userId) {
|
||||||
|
// Remove all tasks with activities in the specified package from the list of recent tasks
|
||||||
|
for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
|
||||||
|
TaskRecord tr = mRecentTasks.get(i);
|
||||||
|
if (tr.userId != userId) continue;
|
||||||
|
|
||||||
|
ComponentName cn = tr.intent.getComponent();
|
||||||
|
if (cn != null && cn.getPackageName().equals(packageName)) {
|
||||||
|
// If the package name matches, remove the task.
|
||||||
|
removeTaskByIdLocked(tr.taskId, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeTasksByRemovedPackageComponentsLocked(String packageName, int userId) {
|
||||||
|
final IPackageManager pm = AppGlobals.getPackageManager();
|
||||||
|
final HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>();
|
||||||
|
|
||||||
|
for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
|
||||||
|
TaskRecord tr = mRecentTasks.get(i);
|
||||||
|
if (tr.userId != userId) continue;
|
||||||
|
|
||||||
|
ComponentName cn = tr.intent.getComponent();
|
||||||
|
if (cn != null && cn.getPackageName().equals(packageName)) {
|
||||||
|
// Skip if component still exists in the package.
|
||||||
|
if (componentsKnownToExist.contains(cn)) continue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
ActivityInfo info = pm.getActivityInfo(cn, 0, userId);
|
||||||
|
if (info != null) {
|
||||||
|
componentsKnownToExist.add(cn);
|
||||||
|
} else {
|
||||||
|
removeTaskByIdLocked(tr.taskId, false);
|
||||||
|
}
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.e(TAG, "Activity info query failed. component=" + cn, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the task with the specified task id.
|
* Removes the task with the specified task id.
|
||||||
*
|
*
|
||||||
@@ -15674,126 +15639,133 @@ public final class ActivityManagerService extends ActivityManagerNative
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle special intents: if this broadcast is from the package
|
final String action = intent.getAction();
|
||||||
// manager about a package being removed, we need to remove all of
|
if (action != null) {
|
||||||
// its activities from the history stack.
|
switch (action) {
|
||||||
final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
|
case Intent.ACTION_UID_REMOVED:
|
||||||
intent.getAction());
|
case Intent.ACTION_PACKAGE_REMOVED:
|
||||||
if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
|
case Intent.ACTION_PACKAGE_CHANGED:
|
||||||
|| Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
|
case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
|
||||||
|| Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
|
case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
|
||||||
|| Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())
|
// Handle special intents: if this broadcast is from the package
|
||||||
|| uidRemoved) {
|
// manager about a package being removed, we need to remove all of
|
||||||
if (checkComponentPermission(
|
// its activities from the history stack.
|
||||||
android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
|
if (checkComponentPermission(
|
||||||
callingPid, callingUid, -1, true)
|
android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
|
||||||
== PackageManager.PERMISSION_GRANTED) {
|
callingPid, callingUid, -1, true)
|
||||||
if (uidRemoved) {
|
!= PackageManager.PERMISSION_GRANTED) {
|
||||||
final Bundle intentExtras = intent.getExtras();
|
String msg = "Permission Denial: " + intent.getAction()
|
||||||
final int uid = intentExtras != null
|
+ " broadcast from " + callerPackage + " (pid=" + callingPid
|
||||||
? intentExtras.getInt(Intent.EXTRA_UID) : -1;
|
+ ", uid=" + callingUid + ")"
|
||||||
if (uid >= 0) {
|
+ " requires "
|
||||||
BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
|
+ android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
|
||||||
synchronized (bs) {
|
Slog.w(TAG, msg);
|
||||||
bs.removeUidStatsLocked(uid);
|
throw new SecurityException(msg);
|
||||||
}
|
|
||||||
mAppOpsService.uidRemoved(uid);
|
|
||||||
}
|
}
|
||||||
} else {
|
switch (action) {
|
||||||
// If resources are unavailable just force stop all
|
case Intent.ACTION_UID_REMOVED:
|
||||||
// those packages and flush the attribute cache as well.
|
final Bundle intentExtras = intent.getExtras();
|
||||||
if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
|
final int uid = intentExtras != null
|
||||||
String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
|
? intentExtras.getInt(Intent.EXTRA_UID) : -1;
|
||||||
if (list != null && (list.length > 0)) {
|
if (uid >= 0) {
|
||||||
for (String pkg : list) {
|
BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
|
||||||
forceStopPackageLocked(pkg, -1, false, true, true, false, false, userId,
|
synchronized (bs) {
|
||||||
"storage unmount");
|
bs.removeUidStatsLocked(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");
|
||||||
|
}
|
||||||
|
cleanupRecentTasksLocked(UserHandle.USER_ALL);
|
||||||
|
sendPackageBroadcastLocked(
|
||||||
|
IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
|
||||||
|
userId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
|
||||||
cleanupRecentTasksLocked(UserHandle.USER_ALL);
|
cleanupRecentTasksLocked(UserHandle.USER_ALL);
|
||||||
sendPackageBroadcastLocked(
|
break;
|
||||||
IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
|
case Intent.ACTION_PACKAGE_REMOVED:
|
||||||
}
|
case Intent.ACTION_PACKAGE_CHANGED:
|
||||||
} else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(
|
Uri data = intent.getData();
|
||||||
intent.getAction())) {
|
String ssp;
|
||||||
cleanupRecentTasksLocked(UserHandle.USER_ALL);
|
if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
|
||||||
} else {
|
boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
|
||||||
Uri data = intent.getData();
|
boolean fullUninstall = removed &&
|
||||||
String ssp;
|
!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
|
||||||
if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
|
if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
|
||||||
boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
|
forceStopPackageLocked(ssp, UserHandle.getAppId(
|
||||||
intent.getAction());
|
intent.getIntExtra(Intent.EXTRA_UID, -1)),
|
||||||
boolean fullUninstall = removed &&
|
false, true, true, false, fullUninstall, userId,
|
||||||
!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
|
removed ? "pkg removed" : "pkg changed");
|
||||||
if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
|
}
|
||||||
forceStopPackageLocked(ssp, UserHandle.getAppId(
|
if (removed) {
|
||||||
intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
|
sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
|
||||||
false, fullUninstall, userId,
|
new String[] {ssp}, userId);
|
||||||
removed ? "pkg removed" : "pkg changed");
|
if (fullUninstall) {
|
||||||
}
|
mAppOpsService.packageRemoved(
|
||||||
if (removed) {
|
intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
|
||||||
sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
|
|
||||||
new String[] {ssp}, userId);
|
|
||||||
if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
|
|
||||||
mAppOpsService.packageRemoved(
|
|
||||||
intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
|
|
||||||
|
|
||||||
// Remove all permissions granted from/to this package
|
// Remove all permissions granted from/to this package
|
||||||
removeUriPermissionsForPackageLocked(ssp, userId, true);
|
removeUriPermissionsForPackageLocked(ssp, userId, true);
|
||||||
|
|
||||||
|
removeTasksByPackageNameLocked(ssp, userId);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
removeTasksByRemovedPackageComponentsLocked(ssp, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
|
||||||
|
if (replacing) {
|
||||||
|
removeTasksByRemovedPackageComponentsLocked(ssp, userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
} else {
|
case Intent.ACTION_TIMEZONE_CHANGED:
|
||||||
String msg = "Permission Denial: " + intent.getAction()
|
// If this is the time zone changed action, queue up a message that will reset
|
||||||
+ " broadcast from " + callerPackage + " (pid=" + callingPid
|
// the timezone of all currently running processes. This message will get
|
||||||
+ ", uid=" + callingUid + ")"
|
// queued up before the broadcast happens.
|
||||||
+ " requires "
|
mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
|
||||||
+ android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
|
break;
|
||||||
Slog.w(TAG, msg);
|
case Intent.ACTION_TIME_CHANGED:
|
||||||
throw new SecurityException(msg);
|
// 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case for adding a package: by default turn on compatibility
|
|
||||||
// mode.
|
|
||||||
} else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
|
|
||||||
Uri data = intent.getData();
|
|
||||||
String ssp;
|
|
||||||
if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
|
|
||||||
mCompatModePackages.handlePackageAddedLocked(ssp,
|
|
||||||
intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
if (Intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
|
|
||||||
mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the user set the time, let all running processes know.
|
|
||||||
*/
|
|
||||||
if (Intent.ACTION_TIME_CHANGED.equals(intent.getAction())) {
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
|
|
||||||
mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
|
|
||||||
ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
|
|
||||||
mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to the sticky list if requested.
|
// Add to the sticky list if requested.
|
||||||
|
|||||||
Reference in New Issue
Block a user