Merge "Add option to enable scrim SRC optimization" into lmp-dev
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index e3cbef5..2e24785 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -1970,9 +1970,9 @@
* {@hide}
*/
public void setProvisioningNotificationVisible(boolean visible, int networkType,
- String extraInfo, String url) {
+ String action) {
try {
- mService.setProvisioningNotificationVisible(visible, networkType, extraInfo, url);
+ mService.setProvisioningNotificationVisible(visible, networkType, action);
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index 974c4cd..a983d88 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -139,8 +139,7 @@
LinkQualityInfo[] getAllLinkQualityInfo();
- void setProvisioningNotificationVisible(boolean visible, int networkType, in String extraInfo,
- in String url);
+ void setProvisioningNotificationVisible(boolean visible, int networkType, in String action);
void setAirplaneMode(boolean enable);
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index b2ebc31..3ada9bb 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -469,6 +469,7 @@
* @param seInfo null-ok SELinux information for the new process.
* @param abi non-null the ABI this app should be started with.
* @param instructionSet null-ok the instruction set to use.
+ * @param appDataDir null-ok the data directory of the app.
* @param zygoteArgs Additional arguments to supply to the zygote process.
*
* @return An object that describes the result of the attempt to start the process.
@@ -484,11 +485,12 @@
String seInfo,
String abi,
String instructionSet,
+ String appDataDir,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
debugFlags, mountExternal, targetSdkVersion, seInfo,
- abi, instructionSet, zygoteArgs);
+ abi, instructionSet, appDataDir, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -592,6 +594,7 @@
* @param seInfo null-ok SELinux information for the new process.
* @param abi the ABI the process should use.
* @param instructionSet null-ok the instruction set to use.
+ * @param appDataDir null-ok the data directory of the app.
* @param extraArgs Additional arguments to supply to the zygote process.
* @return An object that describes the result of the attempt to start the process.
* @throws ZygoteStartFailedEx if process start failed for any reason
@@ -605,6 +608,7 @@
String seInfo,
String abi,
String instructionSet,
+ String appDataDir,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
@@ -668,6 +672,10 @@
argsForZygote.add("--instruction-set=" + instructionSet);
}
+ if (appDataDir != null) {
+ argsForZygote.add("--app-data-dir=" + appDataDir);
+ }
+
argsForZygote.add(processClass);
if (extraArgs != null) {
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index baa133d..1cadf69 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -1138,7 +1138,7 @@
if (parentVirtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID
|| parentAccessibilityViewId == providerHost.getAccessibilityViewId()) {
final AccessibilityNodeInfo parent;
- if (parentAccessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
+ if (parentVirtualDescendantId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
parent = provider.createAccessibilityNodeInfo(parentVirtualDescendantId);
} else {
parent = provider.createAccessibilityNodeInfo(
diff --git a/core/java/android/view/GhostView.java b/core/java/android/view/GhostView.java
index e4500eb..50c927a 100644
--- a/core/java/android/view/GhostView.java
+++ b/core/java/android/view/GhostView.java
@@ -19,6 +19,8 @@
import android.graphics.Matrix;
import android.widget.FrameLayout;
+import java.util.ArrayList;
+
/**
* This view draws another View in an Overlay without changing the parent. It will not be drawn
* by its parent because its visibility is set to INVISIBLE, but will be drawn
@@ -30,6 +32,7 @@
public class GhostView extends View {
private final View mView;
private int mReferences;
+ private boolean mBeingMoved;
private GhostView(View view) {
super(view.getContext());
@@ -75,12 +78,14 @@
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- setGhostedVisibility(View.VISIBLE);
- mView.mGhostView = null;
- final ViewGroup parent = (ViewGroup) mView.getParent();
- if (parent != null) {
- parent.mRecreateDisplayList = true;
- parent.getDisplayList();
+ if (!mBeingMoved) {
+ setGhostedVisibility(View.VISIBLE);
+ mView.mGhostView = null;
+ final ViewGroup parent = (ViewGroup) mView.getParent();
+ if (parent != null) {
+ parent.mRecreateDisplayList = true;
+ parent.getDisplayList();
+ }
}
}
@@ -121,7 +126,9 @@
copySize(viewGroup, parent);
copySize(viewGroup, ghostView);
parent.addView(ghostView);
- overlay.add(parent);
+ ArrayList<View> tempViews = new ArrayList<View>();
+ int firstGhost = moveGhostViewsToTop(overlay.mOverlayViewGroup, tempViews);
+ insertIntoOverlay(overlay.mOverlayViewGroup, parent, ghostView, tempViews, firstGhost);
ghostView.mReferences = previousRefCount;
} else if (matrix != null) {
ghostView.setMatrix(matrix);
@@ -156,4 +163,180 @@
to.setRight(from.getWidth());
to.setBottom(from.getHeight());
}
+
+ /**
+ * Move the GhostViews to the end so that they are on top of other views and it is easier
+ * to do binary search for the correct location for the GhostViews in insertIntoOverlay.
+ *
+ * @return The index of the first GhostView or -1 if no GhostView is in the ViewGroup
+ */
+ private static int moveGhostViewsToTop(ViewGroup viewGroup, ArrayList<View> tempViews) {
+ final int numChildren = viewGroup.getChildCount();
+ if (numChildren == 0) {
+ return -1;
+ } else if (isGhostWrapper(viewGroup.getChildAt(numChildren - 1))) {
+ // GhostViews are already at the end
+ int firstGhost = numChildren - 1;
+ for (int i = numChildren - 2; i >= 0; i--) {
+ if (!isGhostWrapper(viewGroup.getChildAt(i))) {
+ break;
+ }
+ firstGhost = i;
+ }
+ return firstGhost;
+ }
+
+ // Remove all GhostViews from the middle
+ for (int i = numChildren - 2; i >= 0; i--) {
+ View child = viewGroup.getChildAt(i);
+ if (isGhostWrapper(child)) {
+ tempViews.add(child);
+ GhostView ghostView = (GhostView)((ViewGroup)child).getChildAt(0);
+ ghostView.mBeingMoved = true;
+ viewGroup.removeViewAt(i);
+ ghostView.mBeingMoved = false;
+ }
+ }
+
+ final int firstGhost;
+ if (tempViews.isEmpty()) {
+ firstGhost = -1;
+ } else {
+ firstGhost = viewGroup.getChildCount();
+ // Add the GhostViews to the end
+ for (int i = tempViews.size() - 1; i >= 0; i--) {
+ viewGroup.addView(tempViews.get(i));
+ }
+ tempViews.clear();
+ }
+ return firstGhost;
+ }
+
+ /**
+ * Inserts a GhostView into the overlay's ViewGroup in the order in which they
+ * should be displayed by the UI.
+ */
+ private static void insertIntoOverlay(ViewGroup viewGroup, ViewGroup wrapper,
+ GhostView ghostView, ArrayList<View> tempParents, int firstGhost) {
+ if (firstGhost == -1) {
+ viewGroup.addView(wrapper);
+ } else {
+ ArrayList<View> viewParents = new ArrayList<View>();
+ getParents(ghostView.mView, viewParents);
+
+ int index = getInsertIndex(viewGroup, viewParents, tempParents, firstGhost);
+ if (index < 0 || index >= viewGroup.getChildCount()) {
+ viewGroup.addView(wrapper);
+ } else {
+ viewGroup.addView(wrapper, index);
+ }
+ }
+ }
+
+ /**
+ * Find the index into the overlay to insert the GhostView based on the order that the
+ * views should be drawn. This keeps GhostViews layered in the same order
+ * that they are ordered in the UI.
+ */
+ private static int getInsertIndex(ViewGroup overlayViewGroup, ArrayList<View> viewParents,
+ ArrayList<View> tempParents, int firstGhost) {
+ int low = firstGhost;
+ int high = overlayViewGroup.getChildCount() - 1;
+
+ while (low <= high) {
+ int mid = (low + high) / 2;
+ ViewGroup wrapper = (ViewGroup) overlayViewGroup.getChildAt(mid);
+ GhostView midView = (GhostView) wrapper.getChildAt(0);
+ getParents(midView.mView, tempParents);
+ if (isOnTop(viewParents, tempParents)) {
+ low = mid + 1;
+ } else {
+ high = mid - 1;
+ }
+ tempParents.clear();
+ }
+
+ return low;
+ }
+
+ /**
+ * Returns true if view is a GhostView's FrameLayout wrapper.
+ */
+ private static boolean isGhostWrapper(View view) {
+ if (view instanceof FrameLayout) {
+ FrameLayout frameLayout = (FrameLayout) view;
+ if (frameLayout.getChildCount() == 1) {
+ View child = frameLayout.getChildAt(0);
+ return child instanceof GhostView;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if viewParents is from a View that is on top of the comparedWith's view.
+ * The ArrayLists contain the ancestors of views in order from top most grandparent, to
+ * the view itself, in order. The goal is to find the first matching parent and then
+ * compare the draw order of the siblings.
+ */
+ private static boolean isOnTop(ArrayList<View> viewParents, ArrayList<View> comparedWith) {
+ if (viewParents.isEmpty() || comparedWith.isEmpty() ||
+ viewParents.get(0) != comparedWith.get(0)) {
+ // Not the same decorView -- arbitrary ordering
+ return true;
+ }
+ int depth = Math.min(viewParents.size(), comparedWith.size());
+ for (int i = 1; i < depth; i++) {
+ View viewParent = viewParents.get(i);
+ View comparedWithParent = comparedWith.get(i);
+
+ if (viewParent != comparedWithParent) {
+ // i - 1 is the same parent, but these are different children.
+ return isOnTop(viewParent, comparedWithParent);
+ }
+ }
+
+ // one of these is the parent of the other
+ boolean isComparedWithTheParent = (comparedWith.size() == depth);
+ return isComparedWithTheParent;
+ }
+
+ /**
+ * Adds all the parents, grandparents, etc. of view to parents.
+ */
+ private static void getParents(View view, ArrayList<View> parents) {
+ ViewParent parent = view.getParent();
+ if (parent != null && parent instanceof ViewGroup) {
+ getParents((View) parent, parents);
+ }
+ parents.add(view);
+ }
+
+ /**
+ * Returns true if view would be drawn on top of comparedWith or false otherwise.
+ * view and comparedWith are siblings with the same parent. This uses the logic
+ * that dispatchDraw uses to determine which View should be drawn first.
+ */
+ private static boolean isOnTop(View view, View comparedWith) {
+ ViewGroup parent = (ViewGroup) view.getParent();
+
+ final int childrenCount = parent.getChildCount();
+ final ArrayList<View> preorderedList = parent.buildOrderedChildList();
+ final boolean customOrder = preorderedList == null
+ && parent.isChildrenDrawingOrderEnabled();
+ for (int i = 0; i < childrenCount; i++) {
+ int childIndex = customOrder ? parent.getChildDrawingOrder(childrenCount, i) : i;
+ final View child = (preorderedList == null)
+ ? parent.getChildAt(childIndex) : preorderedList.get(childIndex);
+ if (child == view) {
+ return false;
+ } else if (child == comparedWith) {
+ return true;
+ }
+ }
+
+ // Shouldn't get here. Neither of the children is in the parent.
+ // Just return an arbitrary one.
+ return true;
+ }
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 6d3b419..b586caa 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3298,7 +3298,7 @@
* Uses a stable, insertion sort which is commonly O(n) for ViewGroups with very few elevated
* children.
*/
- private ArrayList<View> buildOrderedChildList() {
+ ArrayList<View> buildOrderedChildList() {
final int count = mChildrenCount;
if (count <= 1 || !hasChildWithZ()) return null;
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index c579a15..cca340c 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -79,19 +79,20 @@
* (and replaced by /dev/null) after forking. An integer value
* of -1 in any entry in the array means "ignore this one".
* @param instructionSet null-ok the instruction set to use.
+ * @param appDataDir null-ok the data directory of the app.
*
* @return 0 if this is the child, pid of the child
* if this is the parent, or -1 on error.
*/
public static int forkAndSpecialize(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
- String instructionSet) {
+ String instructionSet, String appDataDir) {
long startTime = SystemClock.elapsedRealtime();
VM_HOOKS.preFork();
checkTime(startTime, "Zygote.preFork");
int pid = nativeForkAndSpecialize(
uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
- instructionSet);
+ instructionSet, appDataDir);
checkTime(startTime, "Zygote.nativeForkAndSpecialize");
VM_HOOKS.postForkCommon();
checkTime(startTime, "Zygote.postForkCommon");
@@ -100,7 +101,7 @@
native private static int nativeForkAndSpecialize(int uid, int gid, int[] gids,int debugFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
- String instructionSet);
+ String instructionSet, String appDataDir);
/**
* Temporary hack: check time since start time and log if over a fixed threshold.
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index fb50b25..2ef8a20 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -93,7 +93,7 @@
new InputStreamReader(socket.getInputStream()), 256);
mSocket.setSoTimeout(CONNECTION_TIMEOUT_MILLIS);
-
+
try {
peer = mSocket.getPeerCredentials();
} catch (IOException ex) {
@@ -245,7 +245,8 @@
checkTime(startTime, "zygoteConnection.runOnce: preForkAndSpecialize");
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid, parsedArgs.gids,
parsedArgs.debugFlags, rlimits, parsedArgs.mountExternal, parsedArgs.seInfo,
- parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet);
+ parsedArgs.niceName, fdsToClose, parsedArgs.instructionSet,
+ parsedArgs.appDataDir);
checkTime(startTime, "zygoteConnection.runOnce: postForkAndSpecialize");
} catch (IOException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
@@ -404,6 +405,12 @@
String instructionSet;
/**
+ * The app data directory. May be null, e.g., for the system server. Note that this might
+ * not be reliable in the case of process-sharing apps.
+ */
+ String appDataDir;
+
+ /**
* Constructs instance and parses args
* @param args zygote command-line args
* @throws IllegalArgumentException
@@ -560,6 +567,8 @@
abiListQuery = true;
} else if (arg.startsWith("--instruction-set=")) {
instructionSet = arg.substring(arg.indexOf('=') + 1);
+ } else if (arg.startsWith("--app-data-dir=")) {
+ appDataDir = arg.substring(arg.indexOf('=') + 1);
} else {
break;
}
@@ -611,7 +620,7 @@
}
// See bug 1092107: large argc can be used for a DOS attack
- if (argc > MAX_ZYGOTE_ARGC) {
+ if (argc > MAX_ZYGOTE_ARGC) {
throw new IOException("max arg count exceeded");
}
@@ -628,7 +637,7 @@
}
/**
- * Applies zygote security policy per bugs #875058 and #1082165.
+ * Applies zygote security policy per bugs #875058 and #1082165.
* Based on the credentials of the process issuing a zygote command:
* <ol>
* <li> uid 0 (root) may specify any uid, gid, and setgroups() list
@@ -659,7 +668,7 @@
/* In normal operation, SYSTEM_UID can only specify a restricted
* set of UIDs. In factory test mode, SYSTEM_UID may specify any uid.
*/
- uidRestricted
+ uidRestricted
= !(factoryTest.equals("1") || factoryTest.equals("2"));
if (uidRestricted
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 451d97a..7ca9374 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -51,6 +51,8 @@
#include "ScopedPrimitiveArray.h"
#include "ScopedUtfChars.h"
+#include "nativebridge/native_bridge.h"
+
namespace {
using android::String8;
@@ -249,20 +251,24 @@
// Create a private mount namespace and bind mount appropriate emulated
// storage for the given user.
-static bool MountEmulatedStorage(uid_t uid, jint mount_mode) {
- if (mount_mode == MOUNT_EXTERNAL_NONE) {
+static bool MountEmulatedStorage(uid_t uid, jint mount_mode, bool force_mount_namespace) {
+ if (mount_mode == MOUNT_EXTERNAL_NONE && !force_mount_namespace) {
return true;
}
- // See storage config details at http://source.android.com/tech/storage/
- userid_t user_id = multiuser_get_user_id(uid);
-
// Create a second private mount namespace for our process
if (unshare(CLONE_NEWNS) == -1) {
ALOGW("Failed to unshare(): %d", errno);
return false;
}
+ if (mount_mode == MOUNT_EXTERNAL_NONE) {
+ return true;
+ }
+
+ // See storage config details at http://source.android.com/tech/storage/
+ userid_t user_id = multiuser_get_user_id(uid);
+
// Create bind mounts to expose external storage
if (mount_mode == MOUNT_EXTERNAL_MULTIUSER || mount_mode == MOUNT_EXTERNAL_MULTIUSER_ALL) {
// These paths must already be created by init.rc
@@ -422,7 +428,7 @@
jint mount_external,
jstring java_se_info, jstring java_se_name,
bool is_system_server, jintArray fdsToClose,
- jstring instructionSet) {
+ jstring instructionSet, jstring dataDir) {
uint64_t start = MsTime();
SetSigChldHandler();
ckTime(start, "ForkAndSpecializeCommon:SetSigChldHandler");
@@ -446,7 +452,13 @@
DropCapabilitiesBoundingSet(env);
- if (!MountEmulatedStorage(uid, mount_external)) {
+ bool need_native_bridge = false;
+ if (instructionSet != NULL) {
+ ScopedUtfChars isa_string(env, instructionSet);
+ need_native_bridge = android::NeedsNativeBridge(isa_string.c_str());
+ }
+
+ if (!MountEmulatedStorage(uid, mount_external, need_native_bridge)) {
ALOGW("Failed to mount emulated storage: %d", errno);
if (errno == ENOTCONN || errno == EROFS) {
// When device is actively encrypting, we get ENOTCONN here
@@ -475,6 +487,17 @@
SetRLimits(env, javaRlimits);
+ if (!is_system_server && need_native_bridge) {
+ // Set the environment for the apps running with native bridge.
+ ScopedUtfChars isa_string(env, instructionSet); // Known non-null because of need_native_...
+ if (dataDir == NULL) {
+ android::PreInitializeNativeBridge(NULL, isa_string.c_str());
+ } else {
+ ScopedUtfChars data_dir(env, dataDir);
+ android::PreInitializeNativeBridge(data_dir.c_str(), isa_string.c_str());
+ }
+ }
+
int rc = setresgid(gid, gid, gid);
if (rc == -1) {
ALOGE("setresgid(%d) failed", gid);
@@ -563,7 +586,7 @@
JNIEnv* env, jclass, jint uid, jint gid, jintArray gids,
jint debug_flags, jobjectArray rlimits,
jint mount_external, jstring se_info, jstring se_name,
- jintArray fdsToClose, jstring instructionSet) {
+ jintArray fdsToClose, jstring instructionSet, jstring appDataDir) {
// Grant CAP_WAKE_ALARM to the Bluetooth process.
jlong capabilities = 0;
if (uid == AID_BLUETOOTH) {
@@ -572,7 +595,7 @@
return ForkAndSpecializeCommon(env, uid, gid, gids, debug_flags,
rlimits, capabilities, capabilities, mount_external, se_info,
- se_name, false, fdsToClose, instructionSet);
+ se_name, false, fdsToClose, instructionSet, appDataDir);
}
static jint com_android_internal_os_Zygote_nativeForkSystemServer(
@@ -582,7 +605,8 @@
pid_t pid = ForkAndSpecializeCommon(env, uid, gid, gids,
debug_flags, rlimits,
permittedCapabilities, effectiveCapabilities,
- MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL, NULL);
+ MOUNT_EXTERNAL_NONE, NULL, NULL, true, NULL,
+ NULL, NULL);
if (pid > 0) {
// The zygote process checks whether the child process has died or not.
ALOGI("System server process %d has been created", pid);
@@ -601,7 +625,7 @@
static JNINativeMethod gMethods[] = {
{ "nativeForkAndSpecialize",
- "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;)I",
+ "(II[II[[IILjava/lang/String;Ljava/lang/String;[ILjava/lang/String;Ljava/lang/String;)I",
(void *) com_android_internal_os_Zygote_nativeForkAndSpecialize },
{ "nativeForkSystemServer", "(II[II[[IJJ)I",
(void *) com_android_internal_os_Zygote_nativeForkSystemServer }
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index aa42c75..84ada6f 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -566,6 +566,9 @@
}
private void startCreateDocumentActivity() {
+ if (!isResumed()) {
+ return;
+ }
PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
if (info == null) {
return;
@@ -724,10 +727,35 @@
}
}
+ // Handle selected page changes making sure they are in the doc.
PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info;
final int pageCount = (info != null) ? getAdjustedPageCount(info) : 0;
PageRange[] pageRanges = printJobInfo.getPages();
- updateSelectedPages(pageRanges, pageCount);
+ if (pageRanges != null && pageCount > 0) {
+ pageRanges = PageRangeUtils.normalize(pageRanges);
+
+ List<PageRange> validatedList = new ArrayList<>();
+ final int rangeCount = pageRanges.length;
+ for (int i = 0; i < rangeCount; i++) {
+ PageRange pageRange = pageRanges[i];
+ if (pageRange.getEnd() >= pageCount) {
+ final int rangeStart = pageRange.getStart();
+ final int rangeEnd = pageCount - 1;
+ if (rangeStart <= rangeEnd) {
+ pageRange = new PageRange(rangeStart, rangeEnd);
+ validatedList.add(pageRange);
+ }
+ break;
+ }
+ validatedList.add(pageRange);
+ }
+
+ if (!validatedList.isEmpty()) {
+ PageRange[] validatedArray = new PageRange[validatedList.size()];
+ validatedList.toArray(validatedArray);
+ updateSelectedPages(validatedArray, pageCount);
+ }
+ }
// Update the content if needed.
if (canUpdateDocument()) {
@@ -1347,7 +1375,8 @@
mPrintButton.setImageResource(R.drawable.ic_menu_savetopdf);
mPrintButton.setContentDescription(getString(R.string.savetopdf_button));
}
- if ((mRangeOptionsSpinner.getSelectedItemPosition() == 1
+ if (!mPrintedDocument.getDocumentInfo().laidout
+ ||(mRangeOptionsSpinner.getSelectedItemPosition() == 1
&& (TextUtils.isEmpty(mPageRangeEditText.getText()) || hasErrors()))
|| (mRangeOptionsSpinner.getSelectedItemPosition() == 0
&& (mPrintedDocument.getDocumentInfo() == null || hasErrors()))) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
index b842a6b..1186a33 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
@@ -34,6 +34,7 @@
private float mLastX;
private float mLastY;
private boolean mBlockFlinging;
+ private boolean mTouchCancelled;
public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -87,9 +88,20 @@
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
- boolean isEndGuesture = (ev.getAction() == MotionEvent.ACTION_UP
- || ev.getAction() == MotionEvent.ACTION_CANCEL);
- if (!mTouchEnabled && !isEndGuesture) {
+ if (ev.getAction() == MotionEvent.ACTION_DOWN) {
+ if (!mTouchEnabled) {
+ mTouchCancelled = true;
+ return false;
+ }
+ mTouchCancelled = false;
+ } else if (mTouchCancelled) {
+ return false;
+ } else if (!mTouchEnabled) {
+ MotionEvent cancel = MotionEvent.obtain(ev);
+ cancel.setAction(MotionEvent.ACTION_CANCEL);
+ super.dispatchTouchEvent(ev);
+ cancel.recycle();
+ mTouchCancelled = true;
return false;
}
return super.dispatchTouchEvent(ev);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index a3c64d0..0b1a627 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -745,10 +745,6 @@
mPacManager = new PacManager(mContext, mHandler, EVENT_PROXY_HAS_CHANGED);
- filter = new IntentFilter();
- filter.addAction(CONNECTED_TO_PROVISIONING_NETWORK_ACTION);
- mContext.registerReceiver(mProvisioningReceiver, filter);
-
mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
}
@@ -1947,23 +1943,6 @@
state + "/" + info.getDetailedState());
}
- // Since mobile has the notion of a network/apn that can be used for
- // provisioning we need to check every time we're connected as
- // CaptiveProtalTracker won't detected it because DCT doesn't report it
- // as connected as ACTION_ANY_DATA_CONNECTION_STATE_CHANGED instead its
- // reported as ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN. Which
- // is received by MDST and sent here as EVENT_STATE_CHANGED.
- if (ConnectivityManager.isNetworkTypeMobile(info.getType())
- && (0 != Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.DEVICE_PROVISIONED, 0))
- && (((state == NetworkInfo.State.CONNECTED)
- && (info.getType() == ConnectivityManager.TYPE_MOBILE))
- || info.isConnectedToProvisioningNetwork())) {
- log("ConnectivityChange checkMobileProvisioning for"
- + " TYPE_MOBILE or ProvisioningNetwork");
- checkMobileProvisioning(CheckMp.MAX_TIMEOUT_MS);
- }
-
EventLogTags.writeConnectivityStateChanged(
info.getType(), info.getSubtype(), info.getDetailedState().ordinal());
@@ -2931,733 +2910,25 @@
enabled));
}
- private boolean isMobileDataStateTrackerReady() {
- MobileDataStateTracker mdst =
- (MobileDataStateTracker) mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI];
- return (mdst != null) && (mdst.isReady());
- }
-
- /**
- * The ResultReceiver resultCode for checkMobileProvisioning (CMP_RESULT_CODE)
- */
-
- /**
- * No connection was possible to the network.
- * This is NOT a warm sim.
- */
- private static final int CMP_RESULT_CODE_NO_CONNECTION = 0;
-
- /**
- * A connection was made to the internet, all is well.
- * This is NOT a warm sim.
- */
- private static final int CMP_RESULT_CODE_CONNECTABLE = 1;
-
- /**
- * A connection was made but no dns server was available to resolve a name to address.
- * This is NOT a warm sim since provisioning network is supported.
- */
- private static final int CMP_RESULT_CODE_NO_DNS = 2;
-
- /**
- * A connection was made but could not open a TCP connection.
- * This is NOT a warm sim since provisioning network is supported.
- */
- private static final int CMP_RESULT_CODE_NO_TCP_CONNECTION = 3;
-
- /**
- * A connection was made but there was a redirection, we appear to be in walled garden.
- * This is an indication of a warm sim on a mobile network such as T-Mobile.
- */
- private static final int CMP_RESULT_CODE_REDIRECTED = 4;
-
- /**
- * The mobile network is a provisioning network.
- * This is an indication of a warm sim on a mobile network such as AT&T.
- */
- private static final int CMP_RESULT_CODE_PROVISIONING_NETWORK = 5;
-
- /**
- * The mobile network is provisioning
- */
- private static final int CMP_RESULT_CODE_IS_PROVISIONING = 6;
-
- private AtomicBoolean mIsProvisioningNetwork = new AtomicBoolean(false);
- private AtomicBoolean mIsStartingProvisioning = new AtomicBoolean(false);
-
- private AtomicBoolean mIsCheckingMobileProvisioning = new AtomicBoolean(false);
-
@Override
public int checkMobileProvisioning(int suggestedTimeOutMs) {
- int timeOutMs = -1;
- if (DBG) log("checkMobileProvisioning: E suggestedTimeOutMs=" + suggestedTimeOutMs);
- enforceConnectivityInternalPermission();
-
- final long token = Binder.clearCallingIdentity();
- try {
- timeOutMs = suggestedTimeOutMs;
- if (suggestedTimeOutMs > CheckMp.MAX_TIMEOUT_MS) {
- timeOutMs = CheckMp.MAX_TIMEOUT_MS;
- }
-
- // Check that mobile networks are supported
- if (!isNetworkSupported(ConnectivityManager.TYPE_MOBILE)
- || !isNetworkSupported(ConnectivityManager.TYPE_MOBILE_HIPRI)) {
- if (DBG) log("checkMobileProvisioning: X no mobile network");
- return timeOutMs;
- }
-
- // If we're already checking don't do it again
- // TODO: Add a queue of results...
- if (mIsCheckingMobileProvisioning.getAndSet(true)) {
- if (DBG) log("checkMobileProvisioning: X already checking ignore for the moment");
- return timeOutMs;
- }
-
- // Start off with mobile notification off
- setProvNotificationVisible(false, ConnectivityManager.TYPE_MOBILE_HIPRI, null, null);
-
- CheckMp checkMp = new CheckMp(mContext, this);
- CheckMp.CallBack cb = new CheckMp.CallBack() {
- @Override
- void onComplete(Integer result) {
- if (DBG) log("CheckMp.onComplete: result=" + result);
- NetworkInfo ni =
- mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI].getNetworkInfo();
- switch(result) {
- case CMP_RESULT_CODE_CONNECTABLE:
- case CMP_RESULT_CODE_NO_CONNECTION:
- case CMP_RESULT_CODE_NO_DNS:
- case CMP_RESULT_CODE_NO_TCP_CONNECTION: {
- if (DBG) log("CheckMp.onComplete: ignore, connected or no connection");
- break;
- }
- case CMP_RESULT_CODE_REDIRECTED: {
- if (DBG) log("CheckMp.onComplete: warm sim");
- String url = getMobileProvisioningUrl();
- if (TextUtils.isEmpty(url)) {
- url = getMobileRedirectedProvisioningUrl();
- }
- if (TextUtils.isEmpty(url) == false) {
- if (DBG) log("CheckMp.onComplete: warm (redirected), url=" + url);
- setProvNotificationVisible(true,
- ConnectivityManager.TYPE_MOBILE_HIPRI, ni.getExtraInfo(),
- url);
- } else {
- if (DBG) log("CheckMp.onComplete: warm (redirected), no url");
- }
- break;
- }
- case CMP_RESULT_CODE_PROVISIONING_NETWORK: {
- String url = getMobileProvisioningUrl();
- if (TextUtils.isEmpty(url) == false) {
- if (DBG) log("CheckMp.onComplete: warm (no dns/tcp), url=" + url);
- setProvNotificationVisible(true,
- ConnectivityManager.TYPE_MOBILE_HIPRI, ni.getExtraInfo(),
- url);
- // Mark that we've got a provisioning network and
- // Disable Mobile Data until user actually starts provisioning.
- mIsProvisioningNetwork.set(true);
- MobileDataStateTracker mdst = (MobileDataStateTracker)
- mNetTrackers[ConnectivityManager.TYPE_MOBILE];
-
- // Disable radio until user starts provisioning
- mdst.setRadio(false);
- } else {
- if (DBG) log("CheckMp.onComplete: warm (no dns/tcp), no url");
- }
- break;
- }
- case CMP_RESULT_CODE_IS_PROVISIONING: {
- // FIXME: Need to know when provisioning is done. Probably we can
- // check the completion status if successful we're done if we
- // "timedout" or still connected to provisioning APN turn off data?
- if (DBG) log("CheckMp.onComplete: provisioning started");
- mIsStartingProvisioning.set(false);
- break;
- }
- default: {
- loge("CheckMp.onComplete: ignore unexpected result=" + result);
- break;
- }
- }
- mIsCheckingMobileProvisioning.set(false);
- }
- };
- CheckMp.Params params =
- new CheckMp.Params(checkMp.getDefaultUrl(), timeOutMs, cb);
- if (DBG) log("checkMobileProvisioning: params=" + params);
- // TODO: Reenable when calls to the now defunct
- // MobileDataStateTracker.isProvisioningNetwork() are removed.
- // This code should be moved to the Telephony code.
- // checkMp.execute(params);
- } finally {
- Binder.restoreCallingIdentity(token);
- if (DBG) log("checkMobileProvisioning: X");
- }
- return timeOutMs;
- }
-
- static class CheckMp extends
- AsyncTask<CheckMp.Params, Void, Integer> {
- private static final String CHECKMP_TAG = "CheckMp";
-
- // adb shell setprop persist.checkmp.testfailures 1 to enable testing failures
- private static boolean mTestingFailures;
-
- // Choosing 4 loops as half of them will use HTTPS and the other half HTTP
- private static final int MAX_LOOPS = 4;
-
- // Number of milli-seconds to complete all of the retires
- public static final int MAX_TIMEOUT_MS = 60000;
-
- // The socket should retry only 5 seconds, the default is longer
- private static final int SOCKET_TIMEOUT_MS = 5000;
-
- // Sleep time for network errors
- private static final int NET_ERROR_SLEEP_SEC = 3;
-
- // Sleep time for network route establishment
- private static final int NET_ROUTE_ESTABLISHMENT_SLEEP_SEC = 3;
-
- // Short sleep time for polling :(
- private static final int POLLING_SLEEP_SEC = 1;
-
- private Context mContext;
- private ConnectivityService mCs;
- private TelephonyManager mTm;
- private Params mParams;
-
- /**
- * Parameters for AsyncTask.execute
- */
- static class Params {
- private String mUrl;
- private long mTimeOutMs;
- private CallBack mCb;
-
- Params(String url, long timeOutMs, CallBack cb) {
- mUrl = url;
- mTimeOutMs = timeOutMs;
- mCb = cb;
- }
-
- @Override
- public String toString() {
- return "{" + " url=" + mUrl + " mTimeOutMs=" + mTimeOutMs + " mCb=" + mCb + "}";
- }
- }
-
- // As explained to me by Brian Carlstrom and Kenny Root, Certificates can be
- // issued by name or ip address, for Google its by name so when we construct
- // this HostnameVerifier we'll pass the original Uri and use it to verify
- // the host. If the host name in the original uril fails we'll test the
- // hostname parameter just incase things change.
- static class CheckMpHostnameVerifier implements HostnameVerifier {
- Uri mOrgUri;
-
- CheckMpHostnameVerifier(Uri orgUri) {
- mOrgUri = orgUri;
- }
-
- @Override
- public boolean verify(String hostname, SSLSession session) {
- HostnameVerifier hv = HttpsURLConnection.getDefaultHostnameVerifier();
- String orgUriHost = mOrgUri.getHost();
- boolean retVal = hv.verify(orgUriHost, session) || hv.verify(hostname, session);
- if (DBG) {
- log("isMobileOk: hostnameVerify retVal=" + retVal + " hostname=" + hostname
- + " orgUriHost=" + orgUriHost);
- }
- return retVal;
- }
- }
-
- /**
- * The call back object passed in Params. onComplete will be called
- * on the main thread.
- */
- abstract static class CallBack {
- // Called on the main thread.
- abstract void onComplete(Integer result);
- }
-
- public CheckMp(Context context, ConnectivityService cs) {
- if (Build.IS_DEBUGGABLE) {
- mTestingFailures =
- SystemProperties.getInt("persist.checkmp.testfailures", 0) == 1;
- } else {
- mTestingFailures = false;
- }
-
- mContext = context;
- mCs = cs;
-
- // Setup access to TelephonyService we'll be using.
- mTm = (TelephonyManager) mContext.getSystemService(
- Context.TELEPHONY_SERVICE);
- }
-
- /**
- * Get the default url to use for the test.
- */
- public String getDefaultUrl() {
- // See http://go/clientsdns for usage approval
- String server = Settings.Global.getString(mContext.getContentResolver(),
- Settings.Global.CAPTIVE_PORTAL_SERVER);
- if (server == null) {
- server = "clients3.google.com";
- }
- return "http://" + server + "/generate_204";
- }
-
- /**
- * Detect if its possible to connect to the http url. DNS based detection techniques
- * do not work at all hotspots. The best way to check is to perform a request to
- * a known address that fetches the data we expect.
- */
- private synchronized Integer isMobileOk(Params params) {
- Integer result = CMP_RESULT_CODE_NO_CONNECTION;
- Uri orgUri = Uri.parse(params.mUrl);
- Random rand = new Random();
- mParams = params;
-
- if (mCs.isNetworkSupported(ConnectivityManager.TYPE_MOBILE) == false) {
- result = CMP_RESULT_CODE_NO_CONNECTION;
- log("isMobileOk: X not mobile capable result=" + result);
- return result;
- }
-
- if (mCs.mIsStartingProvisioning.get()) {
- result = CMP_RESULT_CODE_IS_PROVISIONING;
- log("isMobileOk: X is provisioning result=" + result);
- return result;
- }
-
- // See if we've already determined we've got a provisioning connection,
- // if so we don't need to do anything active.
- MobileDataStateTracker mdstDefault = (MobileDataStateTracker)
- mCs.mNetTrackers[ConnectivityManager.TYPE_MOBILE];
- boolean isDefaultProvisioning = mdstDefault.isProvisioningNetwork();
- log("isMobileOk: isDefaultProvisioning=" + isDefaultProvisioning);
-
- MobileDataStateTracker mdstHipri = (MobileDataStateTracker)
- mCs.mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI];
- boolean isHipriProvisioning = mdstHipri.isProvisioningNetwork();
- log("isMobileOk: isHipriProvisioning=" + isHipriProvisioning);
-
- if (isDefaultProvisioning || isHipriProvisioning) {
- result = CMP_RESULT_CODE_PROVISIONING_NETWORK;
- log("isMobileOk: X default || hipri is provisioning result=" + result);
- return result;
- }
-
- try {
- // Continue trying to connect until time has run out
- long endTime = SystemClock.elapsedRealtime() + params.mTimeOutMs;
-
- if (!mCs.isMobileDataStateTrackerReady()) {
- // Wait for MobileDataStateTracker to be ready.
- if (DBG) log("isMobileOk: mdst is not ready");
- while(SystemClock.elapsedRealtime() < endTime) {
- if (mCs.isMobileDataStateTrackerReady()) {
- // Enable fail fast as we'll do retries here and use a
- // hipri connection so the default connection stays active.
- if (DBG) log("isMobileOk: mdst ready, enable fail fast of mobile data");
- mCs.setEnableFailFastMobileData(DctConstants.ENABLED);
- break;
- }
- sleep(POLLING_SLEEP_SEC);
- }
- }
-
- log("isMobileOk: start hipri url=" + params.mUrl);
-
- // First wait until we can start using hipri
- Binder binder = new Binder();
-/*
- while(SystemClock.elapsedRealtime() < endTime) {
- int ret = mCs.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
- Phone.FEATURE_ENABLE_HIPRI, binder);
- if ((ret == PhoneConstants.APN_ALREADY_ACTIVE)
- || (ret == PhoneConstants.APN_REQUEST_STARTED)) {
- log("isMobileOk: hipri started");
- break;
- }
- if (VDBG) log("isMobileOk: hipri not started yet");
- result = CMP_RESULT_CODE_NO_CONNECTION;
- sleep(POLLING_SLEEP_SEC);
- }
-*/
- // Continue trying to connect until time has run out
- while(SystemClock.elapsedRealtime() < endTime) {
- try {
- // Wait for hipri to connect.
- // TODO: Don't poll and handle situation where hipri fails
- // because default is retrying. See b/9569540
- NetworkInfo.State state = mCs
- .getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState();
- if (state != NetworkInfo.State.CONNECTED) {
- if (true/*VDBG*/) {
- log("isMobileOk: not connected ni=" +
- mCs.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI));
- }
- sleep(POLLING_SLEEP_SEC);
- result = CMP_RESULT_CODE_NO_CONNECTION;
- continue;
- }
-
- // Hipri has started check if this is a provisioning url
- MobileDataStateTracker mdst = (MobileDataStateTracker)
- mCs.mNetTrackers[ConnectivityManager.TYPE_MOBILE_HIPRI];
- if (mdst.isProvisioningNetwork()) {
- result = CMP_RESULT_CODE_PROVISIONING_NETWORK;
- if (DBG) log("isMobileOk: X isProvisioningNetwork result=" + result);
- return result;
- } else {
- if (DBG) log("isMobileOk: isProvisioningNetwork is false, continue");
- }
-
- // Get of the addresses associated with the url host. We need to use the
- // address otherwise HttpURLConnection object will use the name to get
- // the addresses and will try every address but that will bypass the
- // route to host we setup and the connection could succeed as the default
- // interface might be connected to the internet via wifi or other interface.
- InetAddress[] addresses;
- try {
- addresses = InetAddress.getAllByName(orgUri.getHost());
- } catch (UnknownHostException e) {
- result = CMP_RESULT_CODE_NO_DNS;
- log("isMobileOk: X UnknownHostException result=" + result);
- return result;
- }
- log("isMobileOk: addresses=" + inetAddressesToString(addresses));
-
- // Get the type of addresses supported by this link
- LinkProperties lp = mCs.getLinkPropertiesForTypeInternal(
- ConnectivityManager.TYPE_MOBILE_HIPRI);
- boolean linkHasIpv4 = lp.hasIPv4Address();
- boolean linkHasIpv6 = lp.hasGlobalIPv6Address();
- log("isMobileOk: linkHasIpv4=" + linkHasIpv4
- + " linkHasIpv6=" + linkHasIpv6);
-
- final ArrayList<InetAddress> validAddresses =
- new ArrayList<InetAddress>(addresses.length);
-
- for (InetAddress addr : addresses) {
- if (((addr instanceof Inet4Address) && linkHasIpv4) ||
- ((addr instanceof Inet6Address) && linkHasIpv6)) {
- validAddresses.add(addr);
- }
- }
-
- if (validAddresses.size() == 0) {
- return CMP_RESULT_CODE_NO_CONNECTION;
- }
-
- int addrTried = 0;
- while (true) {
- // Loop through at most MAX_LOOPS valid addresses or until
- // we run out of time
- if (addrTried++ >= MAX_LOOPS) {
- log("isMobileOk: too many loops tried - giving up");
- break;
- }
- if (SystemClock.elapsedRealtime() >= endTime) {
- log("isMobileOk: spend too much time - giving up");
- break;
- }
-
- InetAddress hostAddr = validAddresses.get(rand.nextInt(
- validAddresses.size()));
-
- // Make a route to host so we check the specific interface.
- if (mCs.requestRouteToHostAddress(ConnectivityManager.TYPE_MOBILE_HIPRI,
- hostAddr.getAddress())) {
- // Wait a short time to be sure the route is established ??
- log("isMobileOk:"
- + " wait to establish route to hostAddr=" + hostAddr);
- sleep(NET_ROUTE_ESTABLISHMENT_SLEEP_SEC);
- } else {
- log("isMobileOk:"
- + " could not establish route to hostAddr=" + hostAddr);
- // Wait a short time before the next attempt
- sleep(NET_ERROR_SLEEP_SEC);
- continue;
- }
-
- // Rewrite the url to have numeric address to use the specific route
- // using http for half the attempts and https for the other half.
- // Doing https first and http second as on a redirected walled garden
- // such as t-mobile uses we get a SocketTimeoutException: "SSL
- // handshake timed out" which we declare as
- // CMP_RESULT_CODE_NO_TCP_CONNECTION. We could change this, but by
- // having http second we will be using logic used for some time.
- URL newUrl;
- String scheme = (addrTried <= (MAX_LOOPS/2)) ? "https" : "http";
- newUrl = new URL(scheme, hostAddr.getHostAddress(),
- orgUri.getPath());
- log("isMobileOk: newUrl=" + newUrl);
-
- HttpURLConnection urlConn = null;
- try {
- // Open the connection set the request headers and get the response
- urlConn = (HttpURLConnection)newUrl.openConnection(
- java.net.Proxy.NO_PROXY);
- if (scheme.equals("https")) {
- ((HttpsURLConnection)urlConn).setHostnameVerifier(
- new CheckMpHostnameVerifier(orgUri));
- }
- urlConn.setInstanceFollowRedirects(false);
- urlConn.setConnectTimeout(SOCKET_TIMEOUT_MS);
- urlConn.setReadTimeout(SOCKET_TIMEOUT_MS);
- urlConn.setUseCaches(false);
- urlConn.setAllowUserInteraction(false);
- // Set the "Connection" to "Close" as by default "Keep-Alive"
- // is used which is useless in this case.
- urlConn.setRequestProperty("Connection", "close");
- int responseCode = urlConn.getResponseCode();
-
- // For debug display the headers
- Map<String, List<String>> headers = urlConn.getHeaderFields();
- log("isMobileOk: headers=" + headers);
-
- // Close the connection
- urlConn.disconnect();
- urlConn = null;
-
- if (mTestingFailures) {
- // Pretend no connection, this tests using http and https
- result = CMP_RESULT_CODE_NO_CONNECTION;
- log("isMobileOk: TESTING_FAILURES, pretend no connction");
- continue;
- }
-
- if (responseCode == 204) {
- // Return
- result = CMP_RESULT_CODE_CONNECTABLE;
- log("isMobileOk: X got expected responseCode=" + responseCode
- + " result=" + result);
- return result;
- } else {
- // Retry to be sure this was redirected, we've gotten
- // occasions where a server returned 200 even though
- // the device didn't have a "warm" sim.
- log("isMobileOk: not expected responseCode=" + responseCode);
- // TODO - it would be nice in the single-address case to do
- // another DNS resolve here, but flushing the cache is a bit
- // heavy-handed.
- result = CMP_RESULT_CODE_REDIRECTED;
- }
- } catch (Exception e) {
- log("isMobileOk: HttpURLConnection Exception" + e);
- result = CMP_RESULT_CODE_NO_TCP_CONNECTION;
- if (urlConn != null) {
- urlConn.disconnect();
- urlConn = null;
- }
- sleep(NET_ERROR_SLEEP_SEC);
- continue;
- }
- }
- log("isMobileOk: X loops|timed out result=" + result);
- return result;
- } catch (Exception e) {
- log("isMobileOk: Exception e=" + e);
- continue;
- }
- }
- log("isMobileOk: timed out");
- } finally {
- log("isMobileOk: F stop hipri");
- mCs.setEnableFailFastMobileData(DctConstants.DISABLED);
-// mCs.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
-// Phone.FEATURE_ENABLE_HIPRI);
-
- // Wait for hipri to disconnect.
- long endTime = SystemClock.elapsedRealtime() + 5000;
-
- while(SystemClock.elapsedRealtime() < endTime) {
- NetworkInfo.State state = mCs
- .getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState();
- if (state != NetworkInfo.State.DISCONNECTED) {
- if (VDBG) {
- log("isMobileOk: connected ni=" +
- mCs.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI));
- }
- sleep(POLLING_SLEEP_SEC);
- continue;
- }
- }
-
- log("isMobileOk: X result=" + result);
- }
- return result;
- }
-
- @Override
- protected Integer doInBackground(Params... params) {
- return isMobileOk(params[0]);
- }
-
- @Override
- protected void onPostExecute(Integer result) {
- log("onPostExecute: result=" + result);
- if ((mParams != null) && (mParams.mCb != null)) {
- mParams.mCb.onComplete(result);
- }
- }
-
- private String inetAddressesToString(InetAddress[] addresses) {
- StringBuffer sb = new StringBuffer();
- boolean firstTime = true;
- for(InetAddress addr : addresses) {
- if (firstTime) {
- firstTime = false;
- } else {
- sb.append(",");
- }
- sb.append(addr);
- }
- return sb.toString();
- }
-
- private void printNetworkInfo() {
- boolean hasIccCard = mTm.hasIccCard();
- int simState = mTm.getSimState();
- log("hasIccCard=" + hasIccCard
- + " simState=" + simState);
- NetworkInfo[] ni = mCs.getAllNetworkInfo();
- if (ni != null) {
- log("ni.length=" + ni.length);
- for (NetworkInfo netInfo: ni) {
- log("netInfo=" + netInfo.toString());
- }
- } else {
- log("no network info ni=null");
- }
- }
-
- /**
- * Sleep for a few seconds then return.
- * @param seconds
- */
- private static void sleep(int seconds) {
- long stopTime = System.nanoTime() + (seconds * 1000000000);
- long sleepTime;
- while ((sleepTime = stopTime - System.nanoTime()) > 0) {
- try {
- Thread.sleep(sleepTime / 1000000);
- } catch (InterruptedException ignored) {
- }
- }
- }
-
- private static void log(String s) {
- Slog.d(ConnectivityService.TAG, "[" + CHECKMP_TAG + "] " + s);
- }
- }
-
- // TODO: Move to ConnectivityManager and make public?
- private static final String CONNECTED_TO_PROVISIONING_NETWORK_ACTION =
- "com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION";
-
- private BroadcastReceiver mProvisioningReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(CONNECTED_TO_PROVISIONING_NETWORK_ACTION)) {
- handleMobileProvisioningAction(intent.getStringExtra("EXTRA_URL"));
- }
- }
- };
-
- private void handleMobileProvisioningAction(String url) {
- // Mark notification as not visible
- setProvNotificationVisible(false, ConnectivityManager.TYPE_MOBILE_HIPRI, null, null);
-
- // Check airplane mode
- boolean isAirplaneModeOn = Settings.System.getInt(mContext.getContentResolver(),
- Settings.Global.AIRPLANE_MODE_ON, 0) == 1;
- // If provisioning network and not in airplane mode handle as a special case,
- // otherwise launch browser with the intent directly.
- if (mIsProvisioningNetwork.get() && !isAirplaneModeOn) {
- if (DBG) log("handleMobileProvisioningAction: on prov network enable then launch");
- mIsProvisioningNetwork.set(false);
-// mIsStartingProvisioning.set(true);
-// MobileDataStateTracker mdst = (MobileDataStateTracker)
-// mNetTrackers[ConnectivityManager.TYPE_MOBILE];
- // Radio was disabled on CMP_RESULT_CODE_PROVISIONING_NETWORK, enable it here
-// mdst.setRadio(true);
-// mdst.setEnableFailFastMobileData(DctConstants.ENABLED);
-// mdst.enableMobileProvisioning(url);
- } else {
- if (DBG) log("handleMobileProvisioningAction: not prov network");
- mIsProvisioningNetwork.set(false);
- // Check for apps that can handle provisioning first
- Intent provisioningIntent = new Intent(TelephonyIntents.ACTION_CARRIER_SETUP);
- List<String> carrierPackages =
- mTelephonyManager.getCarrierPackageNamesForIntent(provisioningIntent);
- if (carrierPackages != null && !carrierPackages.isEmpty()) {
- if (carrierPackages.size() != 1) {
- if (DBG) log("Multiple matching carrier apps found, launching the first.");
- }
- provisioningIntent.setPackage(carrierPackages.get(0));
- provisioningIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- mContext.startActivity(provisioningIntent);
- } else {
- // If no apps exist, use standard URL ACTION_VIEW method
- Intent newIntent = Intent.makeMainSelectorActivity(Intent.ACTION_MAIN,
- Intent.CATEGORY_APP_BROWSER);
- newIntent.setData(Uri.parse(url));
- newIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- try {
- mContext.startActivity(newIntent);
- } catch (ActivityNotFoundException e) {
- loge("handleMobileProvisioningAction: startActivity failed" + e);
- }
- }
- }
+ // TODO: Remove? Any reason to trigger a provisioning check?
+ return -1;
}
private static final String NOTIFICATION_ID = "CaptivePortal.Notification";
private volatile boolean mIsNotificationVisible = false;
- private void setProvNotificationVisible(boolean visible, int networkType, String extraInfo,
- String url) {
+ private void setProvNotificationVisible(boolean visible, int networkType, String action) {
if (DBG) {
log("setProvNotificationVisible: E visible=" + visible + " networkType=" + networkType
- + " extraInfo=" + extraInfo + " url=" + url);
+ + " action=" + action);
}
- Intent intent = null;
- PendingIntent pendingIntent = null;
- if (visible) {
- switch (networkType) {
- case ConnectivityManager.TYPE_WIFI:
- intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
- break;
- case ConnectivityManager.TYPE_MOBILE:
- case ConnectivityManager.TYPE_MOBILE_HIPRI:
- intent = new Intent(CONNECTED_TO_PROVISIONING_NETWORK_ACTION);
- intent.putExtra("EXTRA_URL", url);
- intent.setFlags(0);
- pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
- break;
- default:
- intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
- intent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT |
- Intent.FLAG_ACTIVITY_NEW_TASK);
- pendingIntent = PendingIntent.getActivity(mContext, 0, intent, 0);
- break;
- }
- }
+ Intent intent = new Intent(action);
+ PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, 0);
// Concatenate the range of types onto the range of NetIDs.
int id = MAX_NET_ID + 1 + (networkType - ConnectivityManager.TYPE_NONE);
- setProvNotificationVisibleIntent(visible, id, networkType, extraInfo, pendingIntent);
+ setProvNotificationVisibleIntent(visible, id, networkType, null, pendingIntent);
}
/**
@@ -3860,9 +3131,14 @@
@Override
public void setProvisioningNotificationVisible(boolean visible, int networkType,
- String extraInfo, String url) {
+ String action) {
enforceConnectivityInternalPermission();
- setProvNotificationVisible(visible, networkType, extraInfo, url);
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ setProvNotificationVisible(visible, networkType, action);
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d0463b7..12c98c1 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3176,7 +3176,7 @@
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
- entryPointArgs);
+ app.info.dataDir, entryPointArgs);
checkTime(startTime, "startProcess: returned from zygote!");
if (app.isolated) {
@@ -6324,7 +6324,7 @@
startProcessLocked(procs.get(ip), "on-hold", null);
}
}
-
+
if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
// Start looking for apps that are abusing wake locks.
Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
@@ -6564,7 +6564,7 @@
throw new IllegalArgumentException("File descriptors passed in options");
}
}
-
+
synchronized(this) {
int callingUid = Binder.getCallingUid();
int origUserId = userId;
@@ -6594,7 +6594,7 @@
return getIntentSenderLocked(type, packageName, callingUid, userId,
token, resultWho, requestCode, intents, resolvedTypes, flags, options);
-
+
} catch (RemoteException e) {
throw new SecurityException(e);
}
@@ -6852,7 +6852,7 @@
"setProcessForeground()");
synchronized(this) {
boolean changed = false;
-
+
synchronized (mPidsSelfLocked) {
ProcessRecord pr = mPidsSelfLocked.get(pid);
if (pr == null && isForeground) {
@@ -6888,13 +6888,13 @@
}
}
}
-
+
if (changed) {
updateOomAdjLocked();
}
}
}
-
+
// =========================================================
// PERMISSIONS
// =========================================================
@@ -6956,7 +6956,7 @@
* permission is automatically denied. (Internally a null permission
* string is used when calling {@link #checkComponentPermission} in cases
* when only uid-based security is needed.)
- *
+ *
* This can be called with or without the global lock held.
*/
@Override
@@ -7213,12 +7213,12 @@
if (DEBUG_URI_PERMISSION) Slog.v(TAG,
"Checking grant " + targetPkg + " permission to " + grantUri);
}
-
+
final IPackageManager pm = AppGlobals.getPackageManager();
// If this is not a content: uri, we can't do anything with it.
if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
- if (DEBUG_URI_PERMISSION) Slog.v(TAG,
+ if (DEBUG_URI_PERMISSION) Slog.v(TAG,
"Can't grant URI permission for non-content URI: " + grantUri);
return -1;
}
@@ -7346,7 +7346,7 @@
// to the uri, and the target doesn't. Let's now give this to
// the target.
- if (DEBUG_URI_PERMISSION) Slog.v(TAG,
+ if (DEBUG_URI_PERMISSION) Slog.v(TAG,
"Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
final String authority = grantUri.uri.getAuthority();
@@ -7548,7 +7548,7 @@
final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
perm.targetUid);
if (perms != null) {
- if (DEBUG_URI_PERMISSION) Slog.v(TAG,
+ if (DEBUG_URI_PERMISSION) Slog.v(TAG,
"Removing " + perm.targetUid + " permission to " + perm.uri);
perms.remove(perm.uri);
@@ -8117,7 +8117,7 @@
outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
ProcessList.FOREGROUND_APP_ADJ);
}
-
+
// =========================================================
// TASK MANAGEMENT
// =========================================================
@@ -8519,7 +8519,7 @@
}
}
}
-
+
/**
* TODO: Add mController hook
*/
@@ -8595,7 +8595,7 @@
/**
* Moves an activity, and all of the other activities within the same task, to the bottom
* of the history stack. The activity's order within the task is unchanged.
- *
+ *
* @param token A reference to the activity we wish to move
* @param nonRoot If false then this only works if the activity is the root
* of a task; if true it will work for any activity in a task.
@@ -9016,7 +9016,7 @@
== PackageManager.PERMISSION_GRANTED) {
return null;
}
-
+
PathPermission[] pps = cpi.pathPermissions;
if (pps != null) {
int i = pps.length;
@@ -9597,7 +9597,7 @@
}
}
}
-
+
public final void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) {
if (providers == null) {
@@ -10075,7 +10075,7 @@
return timedout;
}
-
+
public final void activitySlept(IBinder token) {
if (localLOGV) Slog.v(TAG, "Activity slept: token=" + token);
@@ -10150,7 +10150,7 @@
throw new SecurityException("Requires permission "
+ android.Manifest.permission.STOP_APP_SWITCHES);
}
-
+
synchronized(this) {
mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
+ APP_SWITCH_DELAY_TIME;
@@ -10160,14 +10160,14 @@
mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
}
}
-
+
public void resumeAppSwitches() {
if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
+ android.Manifest.permission.STOP_APP_SWITCHES);
}
-
+
synchronized(this) {
// Note that we don't execute any pending app switches... we will
// let those wait until either the timeout, or the next start
@@ -10175,7 +10175,7 @@
mAppSwitchesAllowedTime = 0;
}
}
-
+
boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
int callingPid, int callingUid, String name) {
if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
@@ -10203,7 +10203,7 @@
Slog.w(TAG, name + " request from " + sourceUid + " stopped");
return false;
}
-
+
public void setDebugApp(String packageName, boolean waitForDebugger,
boolean persistent) {
enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
@@ -11177,7 +11177,7 @@
}
}
}
-
+
synchronized(this) {
if (procsToKill != null) {
for (int i=procsToKill.size()-1; i>=0; i--) {
@@ -11186,20 +11186,20 @@
removeProcessLocked(proc, true, false, "system update done");
}
}
-
+
// Now that we have cleaned up any update processes, we
// are ready to start launching real processes and know that
// we won't trample on them any more.
mProcessesReady = true;
}
-
+
Slog.i(TAG, "System now ready");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
SystemClock.uptimeMillis());
synchronized(this) {
// Make sure we have no pre-ready processes sitting around.
-
+
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
ResolveInfo ri = mContext.getPackageManager()
.resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
@@ -11272,7 +11272,7 @@
// Start up initial activity.
mBooting = true;
-
+
try {
if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
Message msg = Message.obtain();
@@ -11333,12 +11333,12 @@
startAppProblemLocked(app);
app.stopFreezingAllLocked();
}
-
+
/**
* Generate a process error record, suitable for attachment to a ProcessRecord.
- *
+ *
* @param app The ProcessRecord in which the error occurred.
- * @param condition Crashing, Application Not Responding, etc. Values are defined in
+ * @param condition Crashing, Application Not Responding, etc. Values are defined in
* ActivityManager.AppErrorStateInfo
* @param activity The activity associated with the crash, if known.
* @param shortMsg Short message describing the crash.
@@ -11347,7 +11347,7 @@
*
* @return Returns a fully-formed AppErrorStateInfo record.
*/
- private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
+ private ActivityManager.ProcessErrorStateInfo generateProcessError(ProcessRecord app,
int condition, String activity, String shortMsg, String longMsg, String stackTrace) {
ActivityManager.ProcessErrorStateInfo report = new ActivityManager.ProcessErrorStateInfo();
@@ -12104,14 +12104,14 @@
} else if (app.notResponding) {
report = app.notRespondingReport;
}
-
+
if (report != null) {
if (errList == null) {
errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
}
errList.add(report);
} else {
- Slog.w(TAG, "Missing app error report, app = " + app.processName +
+ Slog.w(TAG, "Missing app error report, app = " + app.processName +
" crashing = " + app.crashing +
" notResponding = " + app.notResponding);
}
@@ -12170,7 +12170,7 @@
}
if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
// Generate process state info for running application
- ActivityManager.RunningAppProcessInfo currApp =
+ ActivityManager.RunningAppProcessInfo currApp =
new ActivityManager.RunningAppProcessInfo(app.processName,
app.pid, app.getPackageList());
fillInProcMemInfo(app, currApp);
@@ -12252,7 +12252,7 @@
boolean dumpAll = false;
boolean dumpClient = false;
String dumpPackage = null;
-
+
int opti = 0;
while (opti < args.length) {
String opt = args[opti];
@@ -12625,12 +12625,12 @@
}
}
}
-
+
if (mForegroundProcesses.size() > 0) {
synchronized (mPidsSelfLocked) {
boolean printed = false;
for (int i=0; i<mForegroundProcesses.size(); i++) {
- ProcessRecord r = mPidsSelfLocked.get(
+ ProcessRecord r = mPidsSelfLocked.get(
mForegroundProcesses.valueAt(i).pid);
if (dumpPackage != null && (r == null
|| !r.pkgList.containsKey(dumpPackage))) {
@@ -12648,7 +12648,7 @@
}
}
}
-
+
if (mPersistentStartingProcesses.size() > 0) {
if (needSep) pw.println();
needSep = true;
@@ -12666,7 +12666,7 @@
dumpProcessList(pw, this, mRemovedProcesses, " ",
"Removed Norm", "Removed PERS", dumpPackage);
}
-
+
if (mProcessesOnHold.size() > 0) {
if (needSep) pw.println();
needSep = true;
@@ -12677,7 +12677,7 @@
}
needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
-
+
if (mProcessCrashTimes.getMap().size() > 0) {
boolean printed = false;
long now = SystemClock.uptimeMillis();
@@ -13047,7 +13047,7 @@
ArrayList<String> strings;
ArrayList<Integer> objects;
boolean all;
-
+
ItemMatcher() {
all = true;
}
@@ -13132,7 +13132,7 @@
protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
int opti, boolean dumpAll) {
ArrayList<ActivityRecord> activities;
-
+
synchronized (this) {
activities = mStackSupervisor.getDumpActivitiesLocked(name);
}
@@ -13255,7 +13255,7 @@
}
needSep = true;
-
+
if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
for (int user=0; user<mStickyBroadcasts.size(); user++) {
if (needSep) {
@@ -13290,7 +13290,7 @@
}
}
}
-
+
if (!onlyHistory && dumpAll) {
pw.println();
for (BroadcastQueue queue : mBroadcastQueues) {
@@ -13302,7 +13302,7 @@
needSep = true;
printedAnything = true;
}
-
+
if (!printedAnything) {
pw.println(" (nothing)");
}
@@ -13638,7 +13638,7 @@
long realtime = SystemClock.elapsedRealtime();
pw.println("Applications Graphics Acceleration Info:");
pw.println("Uptime: " + uptime + " Realtime: " + realtime);
-
+
for (int i = procs.size() - 1 ; i >= 0 ; i--) {
ProcessRecord r = procs.get(i);
if (r.thread != null) {
@@ -13832,7 +13832,7 @@
boolean oomOnly = false;
boolean isCompact = false;
boolean localOnly = false;
-
+
int opti = 0;
while (opti < args.length) {
String opt = args[opti];
@@ -13866,7 +13866,7 @@
pw.println("Unknown argument: " + opt + "; use -h for help");
}
}
-
+
final boolean isCheckinRequest = scanArgs(args, "--checkin");
long uptime = SystemClock.uptimeMillis();
long realtime = SystemClock.elapsedRealtime();
@@ -14551,7 +14551,7 @@
}
return restart;
}
-
+
// =========================================================
// SERVICES
// =========================================================
@@ -14633,7 +14633,7 @@
return mServices.peekServiceLocked(service, resolvedType);
}
}
-
+
@Override
public boolean stopServiceToken(ComponentName className, IBinder token,
int startId) {
@@ -14855,11 +14855,11 @@
mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
}
}
-
+
// =========================================================
// BACKUP AND RESTORE
// =========================================================
-
+
// Cause the target app to be launched if necessary and its backup agent
// instantiated. The backup agent will invoke backupAgentCreated() on the
// activity manager to announce its creation.
@@ -14922,7 +14922,7 @@
// mBackupAppName describe the app, so that when it binds back to the AM we
// know that it's scheduled for a backup-agent operation.
}
-
+
return true;
}
@@ -15225,7 +15225,7 @@
mReceiverResolver.removeFilter(rl.get(i));
}
}
-
+
private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
ProcessRecord r = mLruProcesses.get(i);
@@ -15631,10 +15631,10 @@
final boolean replacePending =
(intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
-
+
if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
+ " replacePending=" + replacePending);
-
+
int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
if (!ordered && NR > 0) {
// If we are not serializing this broadcast, then send the
@@ -15742,7 +15742,7 @@
int seq = r.intent.getIntExtra("seq", -1);
Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
}
- boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
+ boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
if (!replaced) {
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
@@ -15908,7 +15908,7 @@
Binder.restoreCallingIdentity(origId);
}
}
-
+
// =========================================================
// INSTRUMENTATION
// =========================================================
@@ -15978,17 +15978,17 @@
return true;
}
-
+
/**
- * Report errors that occur while attempting to start Instrumentation. Always writes the
+ * Report errors that occur while attempting to start Instrumentation. Always writes the
* error to the logs, but if somebody is watching, send the report there too. This enables
* the "am" command to report errors with more information.
- *
+ *
* @param watcher The IInstrumentationWatcher. Null if there isn't one.
* @param cn The component name of the instrumentation.
* @param report The error report.
*/
- private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
+ private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher,
ComponentName cn, String report) {
Slog.w(TAG, report);
try {
@@ -16058,7 +16058,7 @@
// =========================================================
// CONFIGURATION
// =========================================================
-
+
public ConfigurationInfo getDeviceConfigurationInfo() {
ConfigurationInfo config = new ConfigurationInfo();
synchronized (this) {
@@ -16148,11 +16148,11 @@
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) {
Slog.i(TAG, "Updating configuration to: " + values);
}
-
+
EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
if (values.locale != null && !initLocale) {
- saveLocaleLocked(values.locale,
+ saveLocaleLocked(values.locale,
!values.locale.equals(mConfiguration.locale),
values.userSetLocale);
}
@@ -16168,7 +16168,7 @@
//mUsageStatsService.noteStartConfig(newConfig);
final Configuration configCopy = new Configuration(mConfiguration);
-
+
// TODO: If our config changes, should we auto dismiss any currently
// showing dialogs?
mShowDialogs = shouldShowDialogs(newConfig);
@@ -16267,7 +16267,7 @@
if(isDiff) {
SystemProperties.set("user.language", l.getLanguage());
SystemProperties.set("user.region", l.getCountry());
- }
+ }
if(isPersist) {
SystemProperties.set("persist.sys.language", l.getLanguage());
@@ -16955,7 +16955,7 @@
}
app.curRawAdj = adj;
-
+
//Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
// " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
if (adj > app.maxAdj) {
@@ -17038,7 +17038,7 @@
// whatever.
}
}
-
+
/**
* Returns true if things are idle enough to perform GCs.
*/
@@ -17052,7 +17052,7 @@
return !processingBroadcasts
&& (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
}
-
+
/**
* Perform GCs on all processes that are waiting for it, but only
* if things are idle.
@@ -17081,11 +17081,11 @@
}
}
}
-
+
scheduleAppGcsLocked();
}
}
-
+
/**
* If all looks good, perform GCs on all processes waiting for them.
*/
@@ -17103,12 +17103,12 @@
*/
final void scheduleAppGcsLocked() {
mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
-
+
if (mProcessesToGc.size() > 0) {
// Schedule a GC for the time to the next process.
ProcessRecord proc = mProcessesToGc.get(0);
Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
-
+
long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
long now = SystemClock.uptimeMillis();
if (when < (now+GC_TIMEOUT)) {
@@ -17117,7 +17117,7 @@
mHandler.sendMessageAtTime(msg, when);
}
}
-
+
/**
* Add a process to the array of processes waiting to be GCed. Keeps the
* list in sorted order by the last GC time. The process can't already be
@@ -17137,7 +17137,7 @@
mProcessesToGc.add(0, proc);
}
}
-
+
/**
* Set up to ask a process to GC itself. This will either do it
* immediately, or put it on the list of processes to gc the next