Merge "Revert "Fix build.""
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java
index 4a13136..81da6af 100644
--- a/cmds/am/src/com/android/commands/am/Am.java
+++ b/cmds/am/src/com/android/commands/am/Am.java
@@ -2033,7 +2033,7 @@
}
try {
- mAm.resizeStack(stackId, bounds);
+ mAm.resizeStack(stackId, bounds, false);
Thread.sleep(delayMs);
} catch (RemoteException e) {
showError("Error: resizing stack " + e);
@@ -2127,8 +2127,8 @@
}
// Resize stacks
- mAm.resizeStack(currentStackInfo.stackId, currentStackBounds);
- mAm.resizeStack(newStackInfo.stackId, newStackBounds);
+ mAm.resizeStack(currentStackInfo.stackId, currentStackBounds, false);
+ mAm.resizeStack(newStackInfo.stackId, newStackBounds, false);
} catch (RemoteException e) {
}
}
diff --git a/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
index d1f7a00..c9b9e58 100644
--- a/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
+++ b/cmds/appops/src/com/android/commands/appops/AppOpsCommand.java
@@ -168,7 +168,12 @@
final IPackageManager pm = ActivityThread.getPackageManager();
final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
ServiceManager.getService(Context.APP_OPS_SERVICE));
- final int uid = pm.getPackageUid(packageName, userId);
+ final int uid;
+ if ("root".equals(packageName)) {
+ uid = 0;
+ } else {
+ uid = pm.getPackageUid(packageName, userId);
+ }
if (uid < 0) {
System.err.println("Error: No UID for " + packageName + " in user " + userId);
return;
@@ -211,7 +216,12 @@
final IPackageManager pm = ActivityThread.getPackageManager();
final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
ServiceManager.getService(Context.APP_OPS_SERVICE));
- final int uid = pm.getPackageUid(packageName, userId);
+ final int uid;
+ if ("root".equals(packageName)) {
+ uid = 0;
+ } else {
+ uid = pm.getPackageUid(packageName, userId);
+ }
if (uid < 0) {
System.err.println("Error: No UID for " + packageName + " in user " + userId);
return;
diff --git a/cmds/idmap/create.cpp b/cmds/idmap/create.cpp
index 41395f1..9d60ee1 100644
--- a/cmds/idmap/create.cpp
+++ b/cmds/idmap/create.cpp
@@ -41,7 +41,7 @@
ALOGD("error: fchmod %s: %s\n", path, strerror(errno));
goto fail;
}
- if (TEMP_FAILURE_RETRY(flock(fd, LOCK_EX | LOCK_NB)) != 0) {
+ if (TEMP_FAILURE_RETRY(flock(fd, LOCK_EX)) != 0) {
ALOGD("error: flock %s: %s\n", path, strerror(errno));
goto fail;
}
diff --git a/cmds/idmap/idmap.cpp b/cmds/idmap/idmap.cpp
index 90cfa2c..3ab1915 100644
--- a/cmds/idmap/idmap.cpp
+++ b/cmds/idmap/idmap.cpp
@@ -13,7 +13,8 @@
idmap --help \n\
idmap --fd target overlay fd \n\
idmap --path target overlay idmap \n\
- idmap --scan dir-to-scan target-to-look-for target dir-to-hold-idmaps \n\
+ idmap --scan target-package-name-to-look-for path-to-target-apk dir-to-hold-idmaps \\\
+ dir-to-scan [additional-dir-to-scan [additional-dir-to-scan [...]]]\n\
idmap --inspect idmap \n\
\n\
DESCRIPTION \n\
@@ -49,9 +50,9 @@
'overlay' (path to apk); write results to 'idmap' (path). \n\
\n\
--scan: non-recursively search directory 'dir-to-scan' (path) for overlay packages with \n\
- target package 'target-to-look-for' (package name) present at 'target' (path to \n\
- apk). For each overlay package found, create an idmap file in 'dir-to-hold-idmaps' \n\
- (path). \n\
+ target package 'target-package-name-to-look-for' (package name) present at\n\
+ 'path-to-target-apk' (path to apk). For each overlay package found, create an\n\
+ idmap file in 'dir-to-hold-idmaps' (path). \n\
\n\
--inspect: decode the binary format of 'idmap' (path) and display the contents in a \n\
debug-friendly format. \n\
@@ -166,19 +167,14 @@
return idmap_create_path(target_apk_path, overlay_apk_path, idmap_path);
}
- int maybe_scan(const char *overlay_dir, const char *target_package_name,
- const char *target_apk_path, const char *idmap_dir)
+ int maybe_scan(const char *target_package_name, const char *target_apk_path,
+ const char *idmap_dir, const android::Vector<const char *> *overlay_dirs)
{
if (!verify_root_or_system()) {
fprintf(stderr, "error: permission denied: not user root or user system\n");
return -1;
}
- if (!verify_directory_readable(overlay_dir)) {
- ALOGD("error: no read access to %s: %s\n", overlay_dir, strerror(errno));
- return -1;
- }
-
if (!verify_file_readable(target_apk_path)) {
ALOGD("error: failed to read apk %s: %s\n", target_apk_path, strerror(errno));
return -1;
@@ -189,7 +185,16 @@
return -1;
}
- return idmap_scan(overlay_dir, target_package_name, target_apk_path, idmap_dir);
+ const size_t N = overlay_dirs->size();
+ for (size_t i = 0; i < N; i++) {
+ const char *dir = overlay_dirs->itemAt(i);
+ if (!verify_directory_readable(dir)) {
+ ALOGD("error: no read access to %s: %s\n", dir, strerror(errno));
+ return -1;
+ }
+ }
+
+ return idmap_scan(target_package_name, target_apk_path, idmap_dir, overlay_dirs);
}
int maybe_inspect(const char *idmap_path)
@@ -230,8 +235,12 @@
return maybe_create_path(argv[2], argv[3], argv[4]);
}
- if (argc == 6 && !strcmp(argv[1], "--scan")) {
- return maybe_scan(argv[2], argv[3], argv[4], argv[5]);
+ if (argc >= 6 && !strcmp(argv[1], "--scan")) {
+ android::Vector<const char *> v;
+ for (int i = 5; i < argc; i++) {
+ v.push(argv[i]);
+ }
+ return maybe_scan(argv[2], argv[3], argv[4], &v);
}
if (argc == 3 && !strcmp(argv[1], "--inspect")) {
diff --git a/cmds/idmap/idmap.h b/cmds/idmap/idmap.h
index f507dd8..8d4210b 100644
--- a/cmds/idmap/idmap.h
+++ b/cmds/idmap/idmap.h
@@ -1,9 +1,11 @@
+
#ifndef _IDMAP_H_
#define _IDMAP_H_
#define LOG_TAG "idmap"
#include <utils/Log.h>
+#include <utils/Vector.h>
#include <errno.h>
#include <stdio.h>
@@ -26,8 +28,8 @@
// Regarding target_package_name: the idmap_scan implementation should
// be able to extract this from the manifest in target_apk_path,
// simplifying the external API.
-int idmap_scan(const char *overlay_dir, const char *target_package_name,
- const char *target_apk_path, const char *idmap_dir);
+int idmap_scan(const char *target_package_name, const char *target_apk_path,
+ const char *idmap_dir, const android::Vector<const char *> *overlay_dirs);
int idmap_inspect(const char *idmap_path);
diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp
index 612a7eb..f1b2f9e 100644
--- a/cmds/idmap/scan.cpp
+++ b/cmds/idmap/scan.cpp
@@ -25,8 +25,7 @@
bool operator<(Overlay const& rhs) const
{
- // Note: order is reversed by design
- return rhs.priority < priority;
+ return rhs.priority > priority;
}
String8 apk_path;
@@ -167,8 +166,8 @@
}
}
-int idmap_scan(const char *overlay_dir, const char *target_package_name,
- const char *target_apk_path, const char *idmap_dir)
+int idmap_scan(const char *target_package_name, const char *target_apk_path,
+ const char *idmap_dir, const android::Vector<const char *> *overlay_dirs)
{
String8 filename = String8(idmap_dir);
filename.appendPath("overlays.list");
@@ -176,45 +175,49 @@
return EXIT_FAILURE;
}
- DIR *dir = opendir(overlay_dir);
- if (dir == NULL) {
- return EXIT_FAILURE;
- }
-
SortedVector<Overlay> overlayVector;
- struct dirent *dirent;
- while ((dirent = readdir(dir)) != NULL) {
- struct stat st;
- char overlay_apk_path[PATH_MAX + 1];
- snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name);
- if (stat(overlay_apk_path, &st) < 0) {
- continue;
- }
- if (!S_ISREG(st.st_mode)) {
- continue;
+ const size_t N = overlay_dirs->size();
+ for (size_t i = 0; i < N; ++i) {
+ const char *overlay_dir = overlay_dirs->itemAt(i);
+ DIR *dir = opendir(overlay_dir);
+ if (dir == NULL) {
+ return EXIT_FAILURE;
}
- int priority = parse_apk(overlay_apk_path, target_package_name);
- if (priority < 0) {
- continue;
+ struct dirent *dirent;
+ while ((dirent = readdir(dir)) != NULL) {
+ struct stat st;
+ char overlay_apk_path[PATH_MAX + 1];
+ snprintf(overlay_apk_path, PATH_MAX, "%s/%s", overlay_dir, dirent->d_name);
+ if (stat(overlay_apk_path, &st) < 0) {
+ continue;
+ }
+ if (!S_ISREG(st.st_mode)) {
+ continue;
+ }
+
+ int priority = parse_apk(overlay_apk_path, target_package_name);
+ if (priority < 0) {
+ continue;
+ }
+
+ String8 idmap_path(idmap_dir);
+ idmap_path.appendPath(flatten_path(overlay_apk_path + 1));
+ idmap_path.append("@idmap");
+
+ if (idmap_create_path(target_apk_path, overlay_apk_path, idmap_path.string()) != 0) {
+ ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n",
+ target_apk_path, overlay_apk_path, idmap_path.string());
+ continue;
+ }
+
+ Overlay overlay(String8(overlay_apk_path), idmap_path, priority);
+ overlayVector.add(overlay);
}
- String8 idmap_path(idmap_dir);
- idmap_path.appendPath(flatten_path(overlay_apk_path + 1));
- idmap_path.append("@idmap");
-
- if (idmap_create_path(target_apk_path, overlay_apk_path, idmap_path.string()) != 0) {
- ALOGE("error: failed to create idmap for target=%s overlay=%s idmap=%s\n",
- target_apk_path, overlay_apk_path, idmap_path.string());
- continue;
- }
-
- Overlay overlay(String8(overlay_apk_path), idmap_path, priority);
- overlayVector.add(overlay);
+ closedir(dir);
}
- closedir(dir);
-
if (!writePackagesList(filename.string(), overlayVector)) {
return EXIT_FAILURE;
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index faa3a43..b97f947 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -757,9 +757,10 @@
case RESIZE_STACK_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
- int stackId = data.readInt();
+ final int stackId = data.readInt();
Rect r = Rect.CREATOR.createFromParcel(data);
- resizeStack(stackId, r);
+ final boolean allowResizeInDockedMode = data.readInt() == 1;
+ resizeStack(stackId, r, allowResizeInDockedMode);
reply.writeNoException();
return true;
}
@@ -3554,13 +3555,15 @@
reply.recycle();
}
@Override
- public void resizeStack(int stackId, Rect r) throws RemoteException
+ public void resizeStack(int stackId, Rect r, boolean allowResizeInDockedMode)
+ throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IActivityManager.descriptor);
data.writeInt(stackId);
r.writeToParcel(data, 0);
+ data.writeInt(allowResizeInDockedMode ? 1 : 0);
mRemote.transact(RESIZE_STACK_TRANSACTION, data, reply, 0);
reply.readException();
data.recycle();
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index e23620d..c26a44c 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -143,7 +143,7 @@
public void moveTaskToStack(int taskId, int stackId, boolean toTop) throws RemoteException;
public void moveTaskToDockedStack(int taskId, int createMode, boolean toTop)
throws RemoteException;
- public void resizeStack(int stackId, Rect bounds) throws RemoteException;
+ public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) throws RemoteException;
public void positionTaskInStack(int taskId, int stackId, int position) throws RemoteException;
public List<StackInfo> getAllStackInfos() throws RemoteException;
public StackInfo getStackInfo(int stackId) throws RemoteException;
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 3f40484..a83e722 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -50,12 +50,13 @@
public static final int POLICY_ALLOW_BACKGROUND_BATTERY_SAVE = 0x2;
/* RULE_* are not masks and they must be exclusive */
+ public static final int RULE_UNKNOWN = -1;
/** All network traffic should be allowed. */
- public static final int RULE_ALLOW_ALL = 0x0;
+ public static final int RULE_ALLOW_ALL = 0;
/** Reject traffic on metered networks. */
- public static final int RULE_REJECT_METERED = 0x1;
+ public static final int RULE_REJECT_METERED = 1;
/** Reject traffic on all networks. */
- public static final int RULE_REJECT_ALL = 0x2;
+ public static final int RULE_REJECT_ALL = 2;
public static final int FIREWALL_RULE_DEFAULT = 0;
public static final int FIREWALL_RULE_ALLOW = 1;
@@ -326,25 +327,4 @@
// nothing found above; we can apply policy to UID
return true;
}
-
- /** {@hide} */
- public static void dumpPolicy(PrintWriter fout, int policy) {
- fout.write("[");
- if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
- fout.write("REJECT_METERED_BACKGROUND");
- }
- fout.write("]");
- }
-
- /** {@hide} */
- public static void dumpRules(PrintWriter fout, int rules) {
- fout.write("[");
- if ((rules & RULE_REJECT_METERED) != 0) {
- fout.write("REJECT_METERED");
- } else if ((rules & RULE_REJECT_ALL) != 0) {
- fout.write("REJECT_ALL");
- }
- fout.write("]");
- }
-
}
diff --git a/core/java/android/os/Debug.java b/core/java/android/os/Debug.java
index 97b85e2..fdd34f5 100644
--- a/core/java/android/os/Debug.java
+++ b/core/java/android/os/Debug.java
@@ -471,7 +471,7 @@
* </tbody>
* </table>
*/
- public String getMemoryStat(String statName) {
+ public String getMemoryStat(String statName) {
switch(statName) {
case "summary.java-heap":
return Integer.toString(getSummaryJavaHeap());
@@ -1538,7 +1538,13 @@
/**
* Retrieves information about this processes memory usages. This information is broken down by
- * how much is in use by dalivk, the native heap, and everything else.
+ * how much is in use by dalvik, the native heap, and everything else.
+ *
+ * <p><b>Note:</b> this method directly retrieves memory information for the give process
+ * from low-level data available to it. It may not be able to retrieve information about
+ * some protected allocations, such as graphics. If you want to be sure you can see
+ * all information about allocations by the process, use instead
+ * {@link android.app.ActivityManager#getProcessMemoryInfo(int[])}.</p>
*/
public static native void getMemoryInfo(MemoryInfo memoryInfo);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2c7a436..7752ed8 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2408,7 +2408,13 @@
* 1 PFLAG3_APPLYING_INSETS
* 1 PFLAG3_FITTING_SYSTEM_WINDOWS
* 1 PFLAG3_NESTED_SCROLLING_ENABLED
- * 1 PFLAG3_ASSIST_BLOCKED
+ * 1 PFLAG3_SCROLL_INDICATOR_TOP
+ * 1 PFLAG3_SCROLL_INDICATOR_BOTTOM
+ * 1 PFLAG3_SCROLL_INDICATOR_LEFT
+ * 1 PFLAG3_SCROLL_INDICATOR_RIGHT
+ * 1 PFLAG3_SCROLL_INDICATOR_START
+ * 1 PFLAG3_SCROLL_INDICATOR_END
+ * 1 PFLAG3_ASSIST_BLOCKED
* |-------|-------|-------|-------|
*/
@@ -2602,7 +2608,7 @@
* <p>Indicates that we are allowing {@link ViewStructure} to traverse
* into this view.<p>
*/
- static final int PFLAG3_ASSIST_BLOCKED = 0x100;
+ static final int PFLAG3_ASSIST_BLOCKED = 0x4000;
/**
* Always allow a user to over-scroll this view, provided it is a
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 614e82f..c94bc64 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <sys/stat.h>
#include <private/android_filesystem_config.h> // for AID_SYSTEM
@@ -171,11 +172,32 @@
exit(1);
}
- execl(AssetManager::IDMAP_BIN, AssetManager::IDMAP_BIN, "--scan",
- AssetManager::OVERLAY_DIR, AssetManager::TARGET_PACKAGE_NAME,
- AssetManager::TARGET_APK_PATH, AssetManager::IDMAP_DIR, (char*)NULL);
- ALOGE("failed to execl for idmap: %s", strerror(errno));
- exit(1); // should never get here
+ // Generic idmap parameters
+ const char* argv[7];
+ int argc = 0;
+ struct stat st;
+
+ memset(argv, NULL, sizeof(argv));
+ argv[argc++] = AssetManager::IDMAP_BIN;
+ argv[argc++] = "--scan";
+ argv[argc++] = AssetManager::TARGET_PACKAGE_NAME;
+ argv[argc++] = AssetManager::TARGET_APK_PATH;
+ argv[argc++] = AssetManager::IDMAP_DIR;
+
+ // Directories to scan for overlays
+ // /vendor/overlay
+ if (stat(AssetManager::OVERLAY_DIR, &st) == 0) {
+ argv[argc++] = AssetManager::OVERLAY_DIR;
+ }
+
+ // Finally, invoke idmap (if any overlay directory exists)
+ if (argc > 5) {
+ execv(AssetManager::IDMAP_BIN, (char* const*)argv);
+ ALOGE("failed to execl for idmap: %s", strerror(errno));
+ exit(1); // should never get here
+ } else {
+ exit(0);
+ }
}
break;
default: // parent
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 091d57f..9d844a8 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2093,6 +2093,10 @@
<enum name="hdpi" value="240" />
<!-- An extra high density screen, approximately 320dpi. -->
<enum name="xhdpi" value="320" />
+ <!-- An extra extra high density screen, approximately 480dpi. -->
+ <enum name="xxhdpi" value="480" />
+ <!-- An extra extra extra high density screen, approximately 640dpi. -->
+ <enum name="xxxhdpi" value="640" />
</attr>
</declare-styleable>
diff --git a/data/keyboards/Vendor_0079_Product_0011.kl b/data/keyboards/Vendor_0079_Product_0011.kl
index 2ae2a01..32f8c82 100644
--- a/data/keyboards/Vendor_0079_Product_0011.kl
+++ b/data/keyboards/Vendor_0079_Product_0011.kl
@@ -12,10 +12,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Classic NES Controller
+# Classic [S]NES Controller
+key 288 BUTTON_X
key 289 BUTTON_A
key 290 BUTTON_B
+key 291 BUTTON_Y
+key 292 BUTTON_L1
+key 293 BUTTON_R1
key 297 BUTTON_START
key 296 BUTTON_SELECT
diff --git a/docs/html/guide/topics/manifest/compatible-screens-element.jd b/docs/html/guide/topics/manifest/compatible-screens-element.jd
index 3606b15..de921d2 100644
--- a/docs/html/guide/topics/manifest/compatible-screens-element.jd
+++ b/docs/html/guide/topics/manifest/compatible-screens-element.jd
@@ -9,7 +9,7 @@
<pre>
<<a href="#compatible-screens">compatible-screens</a>>
<<a href="#screen">screen</a> android:<a href="#screenSize">screenSize</a>=["small" | "normal" | "large" | "xlarge"]
- android:<a href="#screenDensity">screenDensity</a>=["ldpi" | "mdpi" | "hdpi" | "xhdpi"] />
+ android:<a href="#screenDensity">screenDensity</a>=["ldpi" | "mdpi" | "hdpi" | "xhdpi" | "xxhdpi" | "xxxhdpi"] />
...
</compatible-screens>
</pre>
@@ -94,11 +94,9 @@
<li>{@code mdpi}</li>
<li>{@code hdpi}</li>
<li>{@code xhdpi}</li>
+ <li>{@code xxhdpi}</li>
+ <li>{@code xxxhdpi}</li>
</ul>
- <p class="note"><strong>Note:</strong> This attribute currently does not accept
- {@code xxhdpi} as a valid value, but you can instead specify {@code 480}
- as the value, which is the approximate threshold for xhdpi screens.</p>
-
<p>For information about the different screen densities, see <a
href="{@docRoot}guide/practices/screens_support.html#range">Supporting Multiple Screens</a>.</p>
</dd>
@@ -110,8 +108,8 @@
<dt>example</dt>
<dd>
<p>If your application is compatible with only small and normal screens, regardless
-of screen density, then you must specify eight different {@code <screen>} elements,
-because each screen size has four different density configurations. You must declare each one of
+of screen density, then you must specify twelve different {@code <screen>} elements,
+because each screen size has six different density configurations. You must declare each one of
these; any combination of size and density that you do <em>not</em> specify is considered a screen
configuration with which your application is <em>not</em> compatible. Here's what the manifest
entry looks like if your application is compatible with only small and normal screens:</p>
@@ -125,11 +123,15 @@
<screen android:screenSize="small" android:screenDensity="mdpi" />
<screen android:screenSize="small" android:screenDensity="hdpi" />
<screen android:screenSize="small" android:screenDensity="xhdpi" />
+ <screen android:screenSize="small" android:screenDensity="xxhdpi" />
+ <screen android:screenSize="small" android:screenDensity="xxxhdpi" />
<!-- all normal size screens -->
<screen android:screenSize="normal" android:screenDensity="ldpi" />
<screen android:screenSize="normal" android:screenDensity="mdpi" />
<screen android:screenSize="normal" android:screenDensity="hdpi" />
<screen android:screenSize="normal" android:screenDensity="xhdpi" />
+ <screen android:screenSize="normal" android:screenDensity="xxhdpi" />
+ <screen android:screenSize="normal" android:screenDensity="xxxhdpi" />
</compatible-screens>
<application ... >
...
diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
index c98da47..0dcd02d 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java
@@ -286,51 +286,34 @@
public RootsAdapter(Context context, Collection<RootInfo> roots, Intent includeApps) {
super(context, 0);
- RootItem recents = null;
- RootItem images = null;
- RootItem videos = null;
- RootItem audio = null;
- RootItem downloads = null;
-
- final List<RootInfo> clouds = new ArrayList<>();
- final List<RootInfo> locals = new ArrayList<>();
+ final List<RootItem> libraries = new ArrayList<>();
+ final List<RootItem> clouds = new ArrayList<>();
+ final List<RootItem> locals = new ArrayList<>();
for (RootInfo root : roots) {
- if (root.isRecents()) {
- recents = new RootItem(root);
- } else if (root.isExternalStorage()) {
- locals.add(root);
- } else if (root.isDownloads()) {
- downloads = new RootItem(root);
- } else if (root.isImages()) {
- images = new RootItem(root);
- } else if (root.isVideos()) {
- videos = new RootItem(root);
- } else if (root.isAudio()) {
- audio = new RootItem(root);
- } else {
- clouds.add(root);
+ RootItem item = new RootItem(root);
+ switch (root.derivedType) {
+ case RootInfo.TYPE_LOCAL:
+ locals.add(item);
+ break;
+ case RootInfo.TYPE_CLOUD:
+ clouds.add(item);
+ break;
+ default:
+ libraries.add(item);
+ break;
}
}
final RootComparator comp = new RootComparator();
- Collections.sort(clouds, comp);
+ Collections.sort(libraries, comp);
Collections.sort(locals, comp);
+ Collections.sort(clouds, comp);
- if (recents != null) add(recents);
-
- for (RootInfo cloud : clouds) {
- add(new RootItem(cloud));
- }
-
- if (images != null) add(images);
- if (videos != null) add(videos);
- if (audio != null) add(audio);
- if (downloads != null) add(downloads);
-
- for (RootInfo local : locals) {
- add(new RootItem(local));
- }
+ addAll(libraries);
+ add(new SpacerItem());
+ addAll(locals);
+ addAll(clouds);
if (includeApps != null) {
final PackageManager pm = context.getPackageManager();
@@ -348,9 +331,7 @@
if (apps.size() > 0) {
add(new SpacerItem());
- for (Item item : apps) {
- add(item);
- }
+ addAll(apps);
}
}
}
@@ -387,15 +368,20 @@
}
}
- public static class RootComparator implements Comparator<RootInfo> {
+ public static class RootComparator implements Comparator<RootItem> {
@Override
- public int compare(RootInfo lhs, RootInfo rhs) {
- final int score = DocumentInfo.compareToIgnoreCaseNullable(lhs.title, rhs.title);
+ public int compare(RootItem lhs, RootItem rhs) {
+ // Sort by root type, then title, then summary.
+ int score = lhs.root.derivedType - rhs.root.derivedType;
if (score != 0) {
return score;
- } else {
- return DocumentInfo.compareToIgnoreCaseNullable(lhs.summary, rhs.summary);
}
+ score = DocumentInfo.compareToIgnoreCaseNullable(lhs.root.title, rhs.root.title);
+ if (score != 0) {
+ return score;
+ }
+
+ return DocumentInfo.compareToIgnoreCaseNullable(lhs.root.summary, rhs.root.summary);
}
}
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
index ecf4d6c..17e6a80 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java
@@ -44,6 +44,15 @@
private static final int VERSION_INIT = 1;
private static final int VERSION_DROP_TYPE = 2;
+ // The values of these constants determine the sort order of various roots in the RootsFragment.
+ public static final int TYPE_IMAGES = 1;
+ public static final int TYPE_VIDEO = 2;
+ public static final int TYPE_AUDIO = 3;
+ public static final int TYPE_RECENTS = 4;
+ public static final int TYPE_DOWNLOADS = 5;
+ public static final int TYPE_LOCAL = 6;
+ public static final int TYPE_CLOUD = 7;
+
public String authority;
public String rootId;
public int flags;
@@ -57,6 +66,7 @@
/** Derived fields that aren't persisted */
public String[] derivedMimeTypes;
public int derivedIcon;
+ public int derivedType;
public RootInfo() {
reset();
@@ -76,6 +86,7 @@
derivedMimeTypes = null;
derivedIcon = 0;
+ derivedType = 0;
}
@Override
@@ -158,14 +169,23 @@
// TODO: remove these special case icons
if (isExternalStorage()) {
derivedIcon = R.drawable.ic_root_sdcard;
+ derivedType = TYPE_LOCAL;
} else if (isDownloads()) {
derivedIcon = R.drawable.ic_root_download;
+ derivedType = TYPE_DOWNLOADS;
} else if (isImages()) {
derivedIcon = R.drawable.ic_doc_image;
+ derivedType = TYPE_IMAGES;
} else if (isVideos()) {
derivedIcon = R.drawable.ic_doc_video;
+ derivedType = TYPE_VIDEO;
} else if (isAudio()) {
derivedIcon = R.drawable.ic_doc_audio;
+ derivedType = TYPE_AUDIO;
+ } else if (isRecents()) {
+ derivedType = TYPE_RECENTS;
+ } else {
+ derivedType = TYPE_CLOUD;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java
index 8827065..d3c65d2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java
@@ -16,6 +16,9 @@
package com.android.systemui.recents;
+import static android.app.ActivityManager.DOCKED_STACK_ID;
+import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
+
import android.app.ActivityManager;
import android.app.AlertDialog;
import android.app.Dialog;
@@ -245,7 +248,7 @@
// the focus ends on the selected one.
for (int i = additionalTasks; i >= 0; --i) {
if (mTasks[i] != null) {
- mRecentsView.launchTask(mTasks[i], mBounds[i]);
+ mRecentsView.launchTask(mTasks[i], mBounds[i], FREEFORM_WORKSPACE_STACK_ID);
}
}
}
@@ -273,11 +276,11 @@
// Dismiss the dialog before trying to launch the task
dismissAllowingStateLoss();
- if (mTasks[0].key.stackId != ActivityManager.DOCKED_STACK_ID) {
+ if (mTasks[0].key.stackId != DOCKED_STACK_ID) {
int taskId = mTasks[0].key.id;
mSsp.setTaskResizeable(taskId);
mSsp.dockTask(taskId, createMode);
- mRecentsView.launchTask(mTasks[0], null);
+ mRecentsView.launchTask(mTasks[0], null, DOCKED_STACK_ID);
} else {
Toast.makeText(getContext(), "Already docked", Toast.LENGTH_SHORT);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 1266120..a5fd3eb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -16,6 +16,8 @@
package com.android.systemui.recents.views;
+import static android.app.ActivityManager.INVALID_STACK_ID;
+
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.content.Context;
@@ -185,7 +187,8 @@
TaskView tv = taskViews.get(j);
Task task = tv.getTask();
if (tv.isFocusedTask()) {
- onTaskViewClicked(mTaskStackView, tv, stack, task, false, false, null);
+ onTaskViewClicked(mTaskStackView, tv, stack, task, false, false, null,
+ INVALID_STACK_ID);
return true;
}
}
@@ -194,7 +197,7 @@
}
/** Launches a given task. */
- public boolean launchTask(Task task, Rect taskBounds) {
+ public boolean launchTask(Task task, Rect taskBounds, int destinationStack) {
if (mTaskStackView != null) {
TaskStack stack = mTaskStackView.getStack();
// Iterate the stack views and try and find the given task.
@@ -204,7 +207,7 @@
TaskView tv = taskViews.get(j);
if (tv.getTask() == task) {
onTaskViewClicked(mTaskStackView, tv, stack, task, false, taskBounds != null,
- taskBounds);
+ taskBounds, destinationStack);
return true;
}
}
@@ -226,7 +229,8 @@
if (tasks.get(j).isLaunchTarget) {
Task task = tasks.get(j);
TaskView tv = mTaskStackView.getChildViewForTask(task);
- onTaskViewClicked(mTaskStackView, tv, stack, task, false, false, null);
+ onTaskViewClicked(mTaskStackView, tv, stack, task, false, false, null,
+ INVALID_STACK_ID);
return true;
}
}
@@ -451,12 +455,13 @@
private void postDrawHeaderThumbnailTransitionRunnable(final TaskStackView view,
final TaskView clickedView, final int offsetX, final int offsetY,
final float stackScroll,
- final ActivityOptions.OnAnimationStartedListener animStartedListener) {
+ final ActivityOptions.OnAnimationStartedListener animStartedListener,
+ final int destinationStack) {
Runnable r = new Runnable() {
@Override
public void run() {
overrideDrawHeaderThumbnailTransition(view, clickedView, offsetX, offsetY,
- stackScroll, animStartedListener);
+ stackScroll, animStartedListener, destinationStack);
}
};
@@ -466,9 +471,10 @@
private void overrideDrawHeaderThumbnailTransition(TaskStackView stackView,
TaskView clickedTask, int offsetX, int offsetY, float stackScroll,
- final ActivityOptions.OnAnimationStartedListener animStartedListener) {
+ final ActivityOptions.OnAnimationStartedListener animStartedListener,
+ int destinationStack) {
List<AppTransitionAnimationSpec> specs = getAppTransitionAnimationSpecs(stackView,
- clickedTask, offsetX, offsetY, stackScroll);
+ clickedTask, offsetX, offsetY, stackScroll, destinationStack);
if (specs == null) {
return;
}
@@ -499,8 +505,10 @@
}
private List<AppTransitionAnimationSpec> getAppTransitionAnimationSpecs(TaskStackView stackView,
- TaskView clickedTask, int offsetX, int offsetY, float stackScroll) {
- final int targetStackId = clickedTask.getTask().key.stackId;
+ TaskView clickedTask, int offsetX, int offsetY, float stackScroll,
+ int destinationStack) {
+ final int targetStackId = destinationStack != INVALID_STACK_ID ?
+ destinationStack : clickedTask.getTask().key.stackId;
if (targetStackId != ActivityManager.FREEFORM_WORKSPACE_STACK_ID
&& targetStackId != ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID) {
return null;
@@ -604,9 +612,8 @@
@Override
public void onTaskViewClicked(final TaskStackView stackView, final TaskView tv,
- final TaskStack stack, final Task task, final boolean lockToTask,
- final boolean boundsValid, final Rect bounds) {
-
+ final TaskStack stack, final Task task, final boolean lockToTask,
+ final boolean boundsValid, final Rect bounds, int destinationStack) {
// Notify any callbacks of the launching of a new task
if (mCb != null) {
mCb.onTaskViewClicked();
@@ -654,7 +661,7 @@
};
}
postDrawHeaderThumbnailTransitionRunnable(stackView, tv, offsetX, offsetY, stackScroll,
- animStartedListener);
+ animStartedListener, destinationStack);
opts = ActivityOptions.makeThumbnailAspectScaleUpAnimation(sourceView,
Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8).createAshmemBitmap(),
offsetX, offsetY, transform.rect.width(), transform.rect.height(),
@@ -810,7 +817,7 @@
SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy();
ssp.setTaskResizeable(event.task.key.id);
ssp.dockTask(event.task.key.id, event.dockState.createMode);
- launchTask(event.task, null);
+ launchTask(event.task, null, INVALID_STACK_ID);
}
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 08e4e20..f637407 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -16,7 +16,10 @@
package com.android.systemui.recents.views;
+import static android.app.ActivityManager.INVALID_STACK_ID;
+
import android.animation.ValueAnimator;
+import android.app.ActivityManager;
import android.content.ComponentName;
import android.content.Context;
import android.graphics.Canvas;
@@ -59,7 +62,7 @@
/** The TaskView callbacks */
interface TaskStackViewCallbacks {
public void onTaskViewClicked(TaskStackView stackView, TaskView tv, TaskStack stack, Task t,
- boolean lockToTask, boolean boundsValid, Rect bounds);
+ boolean lockToTask, boolean boundsValid, Rect bounds, int destinationStack);
public void onAllTaskViewsDismissed(ArrayList<Task> removedTasks);
public void onTaskStackFilterTriggered();
public void onTaskStackUnfilterTriggered();
@@ -1227,7 +1230,8 @@
mUIDozeTrigger.stopDozing();
if (mCb != null) {
- mCb.onTaskViewClicked(this, tv, mStack, task, lockToTask, false, null);
+ mCb.onTaskViewClicked(this, tv, mStack, task, lockToTask, false, null,
+ INVALID_STACK_ID);
}
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 75dda9c..f914b20 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -948,13 +948,13 @@
uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
}
- if ((uidRules & RULE_REJECT_ALL) != 0
- || (networkCostly && (uidRules & RULE_REJECT_METERED) != 0)) {
+ if (uidRules == RULE_REJECT_ALL) {
return true;
+ } else if ((uidRules == RULE_REJECT_METERED) && networkCostly) {
+ return true;
+ } else {
+ return false;
}
-
- // no restrictive rules; network is visible
- return false;
}
/**
@@ -3751,7 +3751,7 @@
synchronized(mRulesLock) {
uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
}
- if ((uidRules & (RULE_REJECT_METERED | RULE_REJECT_ALL)) != 0) {
+ if (uidRules != RULE_ALLOW_ALL) {
// we could silently fail or we can filter the available nets to only give
// them those they have access to. Chose the more useful
networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java
index 223519d..87b490d 100644
--- a/services/core/java/com/android/server/DeviceIdleController.java
+++ b/services/core/java/com/android/server/DeviceIdleController.java
@@ -246,6 +246,14 @@
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
int plugged = intent.getIntExtra("plugged", 0);
updateChargingLocked(plugged != 0);
+ } else if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+ if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
+ Uri data = intent.getData();
+ String ssp;
+ if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
+ removePowerSaveWhitelistAppInternal(ssp);
+ }
+ }
} else if (ACTION_STEP_IDLE_STATE.equals(intent.getAction())) {
synchronized (DeviceIdleController.this) {
stepIdleStateLocked();
@@ -972,6 +980,10 @@
filter.addAction(Intent.ACTION_BATTERY_CHANGED);
filter.addAction(ACTION_STEP_IDLE_STATE);
getContext().registerReceiver(mReceiver, filter);
+ filter = new IntentFilter();
+ filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+ filter.addDataScheme("package");
+ getContext().registerReceiver(mReceiver, filter);
mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray);
@@ -984,7 +996,10 @@
public boolean addPowerSaveWhitelistAppInternal(String name) {
synchronized (this) {
try {
- ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name, 0);
+ ApplicationInfo ai = getContext().getPackageManager().getApplicationInfo(name,
+ PackageManager.GET_UNINSTALLED_PACKAGES
+ | PackageManager.GET_DISABLED_COMPONENTS
+ | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
if (mPowerSaveWhitelistUserApps.put(name, UserHandle.getAppId(ai.uid)) == null) {
reportPowerSaveWhitelistChangedLocked();
updateWhitelistAppIdsLocked();
@@ -1610,7 +1625,6 @@
} catch (IOException e) {
}
}
-
}
private void readConfigFileLocked(XmlPullParser parser) {
@@ -1639,7 +1653,10 @@
String name = parser.getAttributeValue(null, "n");
if (name != null) {
try {
- ApplicationInfo ai = pm.getApplicationInfo(name, 0);
+ ApplicationInfo ai = pm.getApplicationInfo(name,
+ PackageManager.GET_UNINSTALLED_PACKAGES
+ | PackageManager.GET_DISABLED_COMPONENTS
+ | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS);
mPowerSaveWhitelistUserApps.put(ai.packageName,
UserHandle.getAppId(ai.uid));
} catch (PackageManager.NameNotFoundException e) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 759a4f3..e7601c2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9161,13 +9161,14 @@
}
@Override
- public void resizeStack(int stackId, Rect bounds) {
+ public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode) {
enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
"resizeStack()");
long ident = Binder.clearCallingIdentity();
try {
synchronized (this) {
- mStackSupervisor.resizeStackLocked(stackId, bounds, !PRESERVE_WINDOWS);
+ mStackSupervisor.resizeStackLocked(
+ stackId, bounds, !PRESERVE_WINDOWS, allowResizeInDockedMode);
}
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index e465009..3cb9887 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -2973,13 +2973,21 @@
}
}
- void resizeStackLocked(int stackId, Rect bounds, boolean preserveWindows) {
+ void resizeStackLocked(int stackId, Rect bounds, boolean preserveWindows,
+ boolean allowResizeInDockedMode) {
final ActivityStack stack = getStack(stackId);
if (stack == null) {
Slog.w(TAG, "resizeStack: stackId " + stackId + " not found.");
return;
}
+ if (!allowResizeInDockedMode
+ && stackId != DOCKED_STACK_ID && getStack(DOCKED_STACK_ID) != null) {
+ // If the docked stack exist we don't allow resizes of stacks not caused by the docked
+ // stack size changing so things don't get out of sync.
+ return;
+ }
+
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "am.resizeStack_" + stackId);
ActivityRecord r = stack.topRunningActivityLocked();
@@ -3014,7 +3022,7 @@
// docked stack tasks to the fullscreen stack.
for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
if (i != DOCKED_STACK_ID && getStack(i) != null) {
- resizeStackLocked(i, null, preserveWindows);
+ resizeStackLocked(i, null, preserveWindows, true);
}
}
@@ -3029,23 +3037,15 @@
} else {
// Docked stacks occupy a dedicated region on screen so the size of all other
// static stacks need to be adjusted so they don't overlap with the docked stack.
- final int leftChange = stack.mBounds.left - bounds.left;
- final int rightChange = stack.mBounds.right - bounds.right;
- final int topChange = stack.mBounds.top - bounds.top;
- final int bottomChange = stack.mBounds.bottom - bounds.bottom;
+ // We get the bounds to use from window manager which has been adjusted for any
+ // screen controls and is also the same for all stacks.
+ mWindowManager.getStackDockedModeBounds(HOME_STACK_ID, tempRect);
for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
if (i != DOCKED_STACK_ID) {
ActivityStack otherStack = getStack(i);
if (otherStack != null) {
- tempRect.set(otherStack.mBounds);
- // We adjust the opposing sides of the other stacks to
- // the side in the dock stack that changed.
- tempRect.left -= rightChange;
- tempRect.right -= leftChange;
- tempRect.top -= bottomChange;
- tempRect.bottom -= topChange;
- resizeStackLocked(i, tempRect, PRESERVE_WINDOWS);
+ resizeStackLocked(i, tempRect, PRESERVE_WINDOWS, true);
}
}
}
@@ -3228,9 +3228,16 @@
// Apps may depend on onResume()/onPause() being called in pairs.
if (wasResumed) {
stack.mResumedActivity = r;
+ // Move the stack in which we are placing the task to the front. We don't use
+ // ActivityManagerService.setFocusedActivityLocked, because if the activity is
+ // already focused, the call will short-circuit and do nothing.
+ stack.moveToFront(reason);
+ } else {
+ // We need to not only move the stack to the front, but also have the activity
+ // focused. This will achieve both goals.
+ mService.setFocusedActivityLocked(r, reason);
}
- // move the stack in which we are placing the task to the front.
- stack.moveToFront(reason);
+
}
return stack;
@@ -4193,7 +4200,7 @@
mLockTaskModeTasks.add(task);
if (task.mLockTaskUid == -1) {
- task.mLockTaskUid = task.mCallingUid;
+ task.mLockTaskUid = task.effectiveUid;
}
if (andResume) {
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 3991489..17ae6dc 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -39,17 +39,17 @@
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
-import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
+import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE;
import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
+import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.NetworkPolicyManager.RULE_UNKNOWN;
import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
-import static android.net.NetworkPolicyManager.dumpPolicy;
-import static android.net.NetworkPolicyManager.dumpRules;
import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
@@ -108,6 +108,7 @@
import android.net.NetworkIdentity;
import android.net.NetworkInfo;
import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
import android.net.NetworkTemplate;
@@ -138,6 +139,7 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
+import android.util.DebugUtils;
import android.util.Log;
import android.util.NtpTrustedTime;
import android.util.Pair;
@@ -147,8 +149,6 @@
import android.util.TrustedTime;
import android.util.Xml;
-import com.android.server.DeviceIdleController;
-import com.android.server.EventLogTags;
import libcore.io.IoUtils;
import com.android.internal.R;
@@ -156,6 +156,8 @@
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.DeviceIdleController;
+import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.google.android.collect.Lists;
@@ -280,6 +282,12 @@
/** Currently derived rules for each UID. */
final SparseIntArray mUidRules = new SparseIntArray();
+ final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
+ final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
+
+ /** Set of states for the child firewall chains. True if the chain is active. */
+ final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
+
/**
* UIDs that have been white-listed to always be able to have network access
* in power save mode, except device idle (doze) still applies.
@@ -444,14 +452,8 @@
// read policy from disk
readPolicyLocked();
- if (mRestrictBackground || mRestrictPower || mDeviceIdleMode) {
- updateRulesForGlobalChangeLocked(false);
- updateNotificationsLocked();
- } else {
- // If we are not in any special mode, we just need to make sure the current
- // app idle state is updated.
- updateRulesForAppIdleLocked();
- }
+ updateRulesForGlobalChangeLocked(false);
+ updateNotificationsLocked();
}
updateScreenOn();
@@ -1796,7 +1798,9 @@
if (mDeviceIdleMode != enabled) {
mDeviceIdleMode = enabled;
if (mSystemReady) {
- updateRulesForDeviceIdleLocked();
+ // Device idle change means we need to rebuild rules for all
+ // known apps, so do a global refresh.
+ updateRulesForGlobalChangeLocked(false);
}
if (enabled) {
EventLogTags.writeDeviceIdleOnPhase("net");
@@ -1934,7 +1938,7 @@
fout.print("UID=");
fout.print(uid);
fout.print(" policy=");
- dumpPolicy(fout, policy);
+ fout.print(DebugUtils.flagsToString(NetworkPolicyManager.class, "POLICY_", policy));
fout.println();
}
fout.decreaseIndent();
@@ -1979,18 +1983,14 @@
fout.print("UID=");
fout.print(uid);
- int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
fout.print(" state=");
fout.print(state);
fout.print(state <= ActivityManager.PROCESS_STATE_TOP ? " (fg)" : " (bg)");
- fout.print(" rules=");
- final int rulesIndex = mUidRules.indexOfKey(uid);
- if (rulesIndex < 0) {
- fout.print("UNKNOWN");
- } else {
- dumpRules(fout, mUidRules.valueAt(rulesIndex));
- }
+ final int rule = mUidRules.get(uid, RULE_UNKNOWN);
+ fout.print(" rule=");
+ fout.print(DebugUtils.valueToString(NetworkPolicyManager.class, "RULE_", rule));
fout.println();
}
@@ -2025,7 +2025,7 @@
updateRulesForUidStateChangeLocked(uid, oldUidState, uidState);
if (mDeviceIdleMode && isProcStateAllowedWhileIdle(oldUidState)
!= isProcStateAllowedWhileIdle(uidState)) {
- updateRulesForDeviceIdleLocked();
+ updateRuleForDeviceIdleLocked(uid);
}
}
}
@@ -2039,7 +2039,7 @@
updateRulesForUidStateChangeLocked(uid, oldUidState,
ActivityManager.PROCESS_STATE_CACHED_EMPTY);
if (mDeviceIdleMode) {
- updateRulesForDeviceIdleLocked();
+ updateRuleForDeviceIdleLocked(uid);
}
}
}
@@ -2086,7 +2086,8 @@
if (mDeviceIdleMode) {
// sync the whitelists before enable dozable chain. We don't care about the rules if
// we are disabling the chain.
- SparseIntArray uidRules = new SparseIntArray();
+ final SparseIntArray uidRules = mUidFirewallDozableRules;
+ uidRules.clear();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
@@ -2110,6 +2111,7 @@
}
setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules);
}
+
enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);
}
@@ -2123,11 +2125,15 @@
setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
}
}
+
+ updateRulesForUidLocked(uid);
}
void updateRulesForAppIdleLocked() {
+ final SparseIntArray uidRules = mUidFirewallStandbyRules;
+ uidRules.clear();
+
// Fully update the app idle firewall chain.
- SparseIntArray uidRules = new SparseIntArray();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
@@ -2138,6 +2144,7 @@
}
}
}
+
setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules);
}
@@ -2150,11 +2157,14 @@
} else {
setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
}
+
+ updateRulesForUidLocked(uid);
}
void updateRulesForAppIdleParoleLocked() {
boolean enableChain = !mUsageStats.isAppIdleParoleOn();
enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain);
+ updateRulesForUidsLocked(mUidFirewallStandbyRules);
}
/**
@@ -2224,6 +2234,12 @@
return true;
}
+ void updateRulesForUidsLocked(SparseIntArray uids) {
+ for (int i = 0; i < uids.size(); i++) {
+ updateRulesForUidLocked(uids.keyAt(i));
+ }
+ }
+
/**
* Applies network rules to bandwidth and firewall controllers based on uid policy.
* @param uid The uid for which to apply the latest policy
@@ -2245,8 +2261,7 @@
final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
final boolean uidForeground = isUidForegroundLocked(uid);
- // derive active rules based on policy and active state
-
+ // Derive active rules based on policy and active state
int appId = UserHandle.getAppId(uid);
int uidRules = RULE_ALLOW_ALL;
if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
@@ -2269,20 +2284,27 @@
}
}
- final int oldRules = mUidRules.get(uid);
+ // Check dozable state, which is whitelist
+ if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)
+ && mUidFirewallDozableRules.get(uid, FIREWALL_RULE_DEFAULT) != FIREWALL_RULE_ALLOW) {
+ uidRules = RULE_REJECT_ALL;
+ }
+ // Check standby state, which is blacklist
+ if (mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)
+ && mUidFirewallStandbyRules.get(uid, FIREWALL_RULE_DEFAULT) == FIREWALL_RULE_DENY) {
+ uidRules = RULE_REJECT_ALL;
+ }
+
+ final int oldRules = mUidRules.get(uid);
if (uidRules == RULE_ALLOW_ALL) {
mUidRules.delete(uid);
} else {
mUidRules.put(uid, uidRules);
}
- // Update bandwidth rules if necessary
- final boolean oldRejectMetered = (oldRules & RULE_REJECT_METERED) != 0;
- final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0;
- if (oldRejectMetered != rejectMetered) {
- setUidNetworkRules(uid, rejectMetered);
- }
+ final boolean rejectMetered = (uidRules == RULE_REJECT_METERED);
+ setUidNetworkRules(uid, rejectMetered);
// dispatch changed rule to existing listeners
if (oldRules != uidRules) {
@@ -2468,6 +2490,12 @@
* Add or remove a uid to the firewall blacklist for all network ifaces.
*/
private void setUidFirewallRule(int chain, int uid, int rule) {
+ if (chain == FIREWALL_CHAIN_DOZABLE) {
+ mUidFirewallDozableRules.put(uid, rule);
+ } else if (chain == FIREWALL_CHAIN_STANDBY) {
+ mUidFirewallStandbyRules.put(uid, rule);
+ }
+
try {
mNetworkManager.setFirewallUidRule(chain, uid, rule);
} catch (IllegalStateException e) {
@@ -2481,6 +2509,12 @@
* Add or remove a uid to the firewall blacklist for all network ifaces.
*/
private void enableFirewallChainLocked(int chain, boolean enable) {
+ if (mFirewallChainStates.indexOfKey(chain) >= 0 &&
+ mFirewallChainStates.get(chain) == enable) {
+ // All is the same, nothing to do.
+ return;
+ }
+ mFirewallChainStates.put(chain, enable);
try {
mNetworkManager.setFirewallChainEnabled(chain, enable);
} catch (IllegalStateException e) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 3e27c95..f7f38db 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -8471,6 +8471,7 @@
final int[] currentUserIds = UserManagerService.getInstance().getUserIds();
+ boolean runtimePermissionsRevoked = false;
int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY;
boolean changedInstallPermission = false;
@@ -8480,6 +8481,17 @@
if (!ps.isSharedUser()) {
origPermissions = new PermissionsState(permissionsState);
permissionsState.reset();
+ } else {
+ // We need to know only about runtime permission changes since the
+ // calling code always writes the install permissions state but
+ // the runtime ones are written only if changed. The only cases of
+ // changed runtime permissions here are promotion of an install to
+ // runtime and revocation of a runtime from a shared user.
+ changedRuntimePermissionUserIds = revokeUnusedSharedUserPermissionsLPw(
+ ps.sharedUser, UserManagerService.getInstance().getUserIds());
+ if (!ArrayUtils.isEmpty(changedRuntimePermissionUserIds)) {
+ runtimePermissionsRevoked = true;
+ }
}
}
@@ -8695,9 +8707,11 @@
ps.installPermissionsFixed = true;
}
- // Persist the runtime permissions state for users with changes.
+ // Persist the runtime permissions state for users with changes. If permissions
+ // were revoked because no app in the shared user declares them we have to
+ // write synchronously to avoid losing runtime permissions state.
for (int userId : changedRuntimePermissionUserIds) {
- mSettings.writeRuntimePermissionsForUserLPr(userId, false);
+ mSettings.writeRuntimePermissionsForUserLPr(userId, runtimePermissionsRevoked);
}
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
@@ -12248,6 +12262,66 @@
}
}
+ private int[] revokeUnusedSharedUserPermissionsLPw(SharedUserSetting su, int[] allUserIds) {
+ // Collect all used permissions in the UID
+ ArraySet<String> usedPermissions = new ArraySet<>();
+ final int packageCount = su.packages.size();
+ for (int i = 0; i < packageCount; i++) {
+ PackageSetting ps = su.packages.valueAt(i);
+ if (ps.pkg == null) {
+ continue;
+ }
+ final int requestedPermCount = ps.pkg.requestedPermissions.size();
+ for (int j = 0; j < requestedPermCount; j++) {
+ String permission = ps.pkg.requestedPermissions.get(j);
+ BasePermission bp = mSettings.mPermissions.get(permission);
+ if (bp != null) {
+ usedPermissions.add(permission);
+ }
+ }
+ }
+
+ PermissionsState permissionsState = su.getPermissionsState();
+ // Prune install permissions
+ List<PermissionState> installPermStates = permissionsState.getInstallPermissionStates();
+ final int installPermCount = installPermStates.size();
+ for (int i = installPermCount - 1; i >= 0; i--) {
+ PermissionState permissionState = installPermStates.get(i);
+ if (!usedPermissions.contains(permissionState.getName())) {
+ BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
+ if (bp != null) {
+ permissionsState.revokeInstallPermission(bp);
+ permissionsState.updatePermissionFlags(bp, UserHandle.USER_ALL,
+ PackageManager.MASK_PERMISSION_FLAGS, 0);
+ }
+ }
+ }
+
+ int[] runtimePermissionChangedUserIds = EmptyArray.INT;
+
+ // Prune runtime permissions
+ for (int userId : allUserIds) {
+ List<PermissionState> runtimePermStates = permissionsState
+ .getRuntimePermissionStates(userId);
+ final int runtimePermCount = runtimePermStates.size();
+ for (int i = runtimePermCount - 1; i >= 0; i--) {
+ PermissionState permissionState = runtimePermStates.get(i);
+ if (!usedPermissions.contains(permissionState.getName())) {
+ BasePermission bp = mSettings.mPermissions.get(permissionState.getName());
+ if (bp != null) {
+ permissionsState.revokeRuntimePermission(bp, userId);
+ permissionsState.updatePermissionFlags(bp, userId,
+ PackageManager.MASK_PERMISSION_FLAGS, 0);
+ runtimePermissionChangedUserIds = ArrayUtils.appendInt(
+ runtimePermissionChangedUserIds, userId);
+ }
+ }
+ }
+ }
+
+ return runtimePermissionChangedUserIds;
+ }
+
private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
String volumeUuid, int[] allUsers, boolean[] perUserInstalled, PackageInstalledInfo res,
UserHandle user) {
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 3c28648..2d87123 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -206,7 +206,8 @@
}
if (distance <= mSideMargin) {
try {
- mDisplayContent.mService.mActivityManager.resizeStack(mTaskStack.mStackId, null);
+ mDisplayContent.mService.mActivityManager.resizeStack(
+ mTaskStack.mStackId, null, true);
} catch (RemoteException e) {
// This can't happen because we are in the same process.
}
@@ -364,7 +365,7 @@
}
mLastResizeRect.set(mTmpRect);
try {
- mDisplayContent.mService.mActivityManager.resizeStack(DOCKED_STACK_ID, mTmpRect);
+ mDisplayContent.mService.mActivityManager.resizeStack(DOCKED_STACK_ID, mTmpRect, true);
} catch (RemoteException e) {
// This can't happen because we are in the same process.
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index ca358b1..b409cea 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -238,8 +238,8 @@
// Post message to inform activity manager of the bounds change simulating
// a one-way call. We do this to prevent a deadlock between window manager
// lock and activity manager lock been held.
- mService.mH.sendMessage(
- mService.mH.obtainMessage(RESIZE_STACK, mStackId, UNUSED, mBounds));
+ mService.mH.sendMessage(mService.mH.obtainMessage(
+ RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mBounds));
}
}
}
@@ -399,8 +399,11 @@
if (dockedStack != null) {
dockedStack.getRawBounds(mTmpRect2);
}
- getInitialDockedStackBounds(mTmpRect, bounds, mStackId, mTmpRect2,
- mDisplayContent.mDividerControllerLocked.getWidthAdjustment());
+ final boolean dockedOnTopOrLeft = WindowManagerService.sDockedStackCreateMode
+ == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
+ getStackDockedModeBounds(mTmpRect, bounds, mStackId, mTmpRect2,
+ mDisplayContent.mDividerControllerLocked.getWidthAdjustment(),
+ dockedOnTopOrLeft);
}
updateDisplayInfo(bounds);
@@ -413,28 +416,60 @@
}
}
+ void getStackDockedModeBoundsLocked(Rect outBounds) {
+ if (mStackId == DOCKED_STACK_ID
+ || mStackId > LAST_STATIC_STACK_ID
+ || mDisplayContent == null) {
+ outBounds.set(mBounds);
+ return;
+ }
+
+ final TaskStack dockedStack = mDisplayContent.getDockedStackLocked();
+ if (dockedStack == null) {
+ // Not sure why you are calling this method when there is no docked stack...
+ throw new IllegalStateException(
+ "Calling getStackDockedModeBoundsLocked() when there is no docked stack.");
+ }
+
+ @DockSide
+ final int dockedSide = dockedStack.getDockSide();
+ if (dockedSide == DOCKED_INVALID) {
+ // Not sure how you got here...Only thing we can do is return current bounds.
+ Slog.e(TAG, "Failed to get valid docked side for docked stack=" + dockedStack);
+ outBounds.set(mBounds);
+ return;
+ }
+
+ mDisplayContent.getLogicalDisplayRect(mTmpRect);
+ dockedStack.getRawBounds(mTmpRect2);
+ final boolean dockedOnTopOrLeft = dockedSide == DOCKED_TOP || dockedSide == DOCKED_LEFT;
+ getStackDockedModeBounds(mTmpRect, outBounds, mStackId, mTmpRect2,
+ mDisplayContent.mDividerControllerLocked.getWidthAdjustment(), dockedOnTopOrLeft);
+
+ }
+
/**
- * Outputs the initial bounds a stack should be given the presence of a docked stack on the
- * display.
+ * Outputs the bounds a stack should be given the presence of a docked stack on the display.
* @param displayRect The bounds of the display the docked stack is on.
* @param outBounds Output bounds that should be used for the stack.
* @param stackId Id of stack we are calculating the bounds for.
* @param dockedBounds Bounds of the docked stack.
- * @param adjustment
+ * @param adjustment Additional adjustment to make to the output bounds close to the side of the
+ * dock.
+ * @param dockOntopOrLeft If the docked stack is on the top or left side of the screen.
*/
- private static void getInitialDockedStackBounds(
- Rect displayRect, Rect outBounds, int stackId, Rect dockedBounds, int adjustment) {
+ private static void getStackDockedModeBounds(
+ Rect displayRect, Rect outBounds, int stackId, Rect dockedBounds, int adjustment,
+ boolean dockOntopOrLeft) {
final boolean dockedStack = stackId == DOCKED_STACK_ID;
final boolean splitHorizontally = displayRect.width() > displayRect.height();
- final boolean topOrLeftCreateMode =
- WindowManagerService.sDockedStackCreateMode == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
outBounds.set(displayRect);
if (dockedStack) {
// The initial bounds of the docked stack when it is created half the screen space and
// its bounds can be adjusted after that. The bounds of all other stacks are adjusted
// to occupy whatever screen space the docked stack isn't occupying.
- if (topOrLeftCreateMode) {
+ if (dockOntopOrLeft) {
if (splitHorizontally) {
outBounds.right = displayRect.centerX() - adjustment;
} else {
@@ -451,7 +486,7 @@
}
// Other stacks occupy whatever space is left by the docked stack.
- if (!topOrLeftCreateMode) {
+ if (!dockOntopOrLeft) {
if (splitHorizontally) {
outBounds.right = dockedBounds.left - adjustment;
} else {
@@ -477,8 +512,10 @@
final Rect bounds = new Rect();
mDisplayContent.getLogicalDisplayRect(bounds);
if (!fullscreen) {
- getInitialDockedStackBounds(bounds, bounds, FULLSCREEN_WORKSPACE_STACK_ID, dockedBounds,
- mDisplayContent.mDividerControllerLocked.getWidth());
+ final boolean dockedOnTopOrLeft = WindowManagerService.sDockedStackCreateMode
+ == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
+ getStackDockedModeBounds(bounds, bounds, FULLSCREEN_WORKSPACE_STACK_ID, dockedBounds,
+ mDisplayContent.mDividerControllerLocked.getWidth(), dockedOnTopOrLeft);
}
final int count = mService.mStackIdToStack.size();
@@ -489,7 +526,8 @@
&& otherStackId >= FIRST_STATIC_STACK_ID
&& otherStackId <= LAST_STATIC_STACK_ID) {
mService.mH.sendMessage(
- mService.mH.obtainMessage(RESIZE_STACK, otherStackId, UNUSED, bounds));
+ mService.mH.obtainMessage(RESIZE_STACK, otherStackId,
+ 1 /*allowResizeInDockedMode*/, bounds));
}
}
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0932f15..f571d9c 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4617,6 +4617,17 @@
}
}
+ public void getStackDockedModeBounds(int stackId, Rect bounds) {
+ synchronized (mWindowMap) {
+ final TaskStack stack = mStackIdToStack.get(stackId);
+ if (stack != null) {
+ stack.getStackDockedModeBoundsLocked(bounds);
+ return;
+ }
+ bounds.setEmpty();
+ }
+ }
+
public void getStackBounds(int stackId, Rect bounds) {
synchronized (mWindowMap) {
final TaskStack stack = mStackIdToStack.get(stackId);
@@ -7779,7 +7790,7 @@
break;
case RESIZE_STACK: {
try {
- mActivityManager.resizeStack(msg.arg1, (Rect) msg.obj);
+ mActivityManager.resizeStack(msg.arg1, (Rect) msg.obj, msg.arg2 == 1);
} catch (RemoteException e) {
// This will not happen since we are in the same process.
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 8b37ec4..13e600e 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -314,6 +314,8 @@
mAppIdleParoled = paroled;
if (DEBUG) Slog.d(TAG, "Changing paroled to " + mAppIdleParoled);
if (paroled) {
+ postParoleEndTimeout();
+ } else {
mLastAppIdleParoledTime = checkAndGetTimeLocked();
postNextParoleTimeout();
}
@@ -404,8 +406,6 @@
if (timeSinceLastParole > mAppIdleParoleIntervalMillis) {
if (DEBUG) Slog.d(TAG, "Crossed default parole interval");
setAppIdleParoled(true);
- // Make sure it ends at some point
- postParoleEndTimeout();
} else {
if (DEBUG) Slog.d(TAG, "Not long enough to go to parole");
postNextParoleTimeout();
@@ -492,7 +492,6 @@
if (!deviceIdle
&& timeSinceLastParole >= mAppIdleParoleIntervalMillis) {
if (DEBUG) Slog.i(TAG, "Bringing idle apps out of inactive state due to deviceIdleMode=false");
- postNextParoleTimeout();
setAppIdleParoled(true);
} else if (deviceIdle) {
if (DEBUG) Slog.i(TAG, "Device idle, back to prison");
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index b2dc29a..93b3f4f 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -73,6 +73,7 @@
import android.os.Parcel;
import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.ResultReceiver;
import android.os.UserHandle;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -1130,6 +1131,11 @@
public boolean unlinkToDeath(DeathRecipient recipient, int flags) {
return false;
}
+
+ @Override
+ public void shellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
+ String[] args, ResultReceiver resultReceiver) {
+ }
};
}
return mBinder;