diff options
31 files changed, 514 insertions, 255 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 4a13136fa8d9..81da6af20eb2 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 @@ public class Am extends BaseCommand { } 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 @@ public class Am extends BaseCommand { } // 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 d1f7a0098e21..c9b9e5862a48 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 @@ public class AppOpsCommand extends BaseCommand { 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 @@ public class AppOpsCommand extends BaseCommand { 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 41395f13ce5f..9d60ee1c0e50 100644 --- a/cmds/idmap/create.cpp +++ b/cmds/idmap/create.cpp @@ -41,7 +41,7 @@ namespace { 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 90cfa2c610f0..3ab191553625 100644 --- a/cmds/idmap/idmap.cpp +++ b/cmds/idmap/idmap.cpp @@ -13,7 +13,8 @@ SYNOPSIS \n\ 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 @@ OPTIONS \n\ '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 @@ NOTES \n\ 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 @@ NOTES \n\ 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 @@ int main(int argc, char **argv) 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 f507dd8530ac..8d4210bcb443 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 @@ int idmap_create_fd(const char *target_apk_path, const char *overlay_apk_path, i // 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 612a7ebb5489..f1b2f9e72ca0 100644 --- a/cmds/idmap/scan.cpp +++ b/cmds/idmap/scan.cpp @@ -25,8 +25,7 @@ namespace { 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 @@ namespace { } } -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 @@ int idmap_scan(const char *overlay_dir, const char *target_package_name, 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; + } + + 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; - } + 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"); + 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; + 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); } - 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 faa3a43f6c2e..b97f94735b9f 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -757,9 +757,10 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM 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 @@ class ActivityManagerProxy implements IActivityManager 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 e23620d9b0ea..c26a44cae57c 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -143,7 +143,7 @@ public interface IActivityManager extends IInterface { 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 3f40484b2595..a83e72240310 100644 --- a/core/java/android/net/NetworkPolicyManager.java +++ b/core/java/android/net/NetworkPolicyManager.java @@ -50,12 +50,13 @@ public class NetworkPolicyManager { 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 @@ public class NetworkPolicyManager { // 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 97b85e2531d0..fdd34f586e8c 100644 --- a/core/java/android/os/Debug.java +++ b/core/java/android/os/Debug.java @@ -471,7 +471,7 @@ public final class Debug * </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 @@ href="{@docRoot}guide/developing/tools/traceview.html">Traceview: A Graphical Lo /** * 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 2c7a43648f2c..7752ed890dc0 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2408,7 +2408,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * 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 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * <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 614e82f803ff..c94bc649014e 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 @@ static void verifySystemIdmaps() 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 091d57f8402c..9d844a880110 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 2ae2a017481f..32f8c829cd65 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 3606b15cabcc..de921d2e03cd 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 @@ parent.link=manifest-intro.html <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 @@ href="{@docRoot}guide/practices/screens_support.html#range">Supporting Multiple <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 @@ href="{@docRoot}guide/practices/screens_support.html#range">Supporting Multiple <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 @@ entry looks like if your application is compatible with only small and normal sc <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 c98da471cd88..0dcd02da442b 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java @@ -286,51 +286,34 @@ public class RootsFragment extends Fragment { 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 @@ public class RootsFragment extends Fragment { if (apps.size() > 0) { add(new SpacerItem()); - for (Item item : apps) { - add(item); - } + addAll(apps); } } } @@ -387,15 +368,20 @@ public class RootsFragment extends Fragment { } } - 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 ecf4d6c3bc99..17e6a801c53e 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 @@ public class RootInfo implements Durable, Parcelable { 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 @@ public class RootInfo implements Durable, Parcelable { /** Derived fields that aren't persisted */ public String[] derivedMimeTypes; public int derivedIcon; + public int derivedType; public RootInfo() { reset(); @@ -76,6 +86,7 @@ public class RootInfo implements Durable, Parcelable { derivedMimeTypes = null; derivedIcon = 0; + derivedType = 0; } @Override @@ -158,14 +169,23 @@ public class RootInfo implements Durable, Parcelable { // 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 88270650ca1c..d3c65d271b62 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 @@ public class RecentsResizeTaskDialog extends DialogFragment { // 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 @@ public class RecentsResizeTaskDialog extends DialogFragment { // 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 126612074a1b..a5fd3eb70fc4 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV } /** 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV } 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV @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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV }; } 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 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV 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 08e4e202e19d..f63740715cb6 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 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal /** 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 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal 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 75dda9c0ae20..f914b2063e23 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -948,13 +948,13 @@ public class ConnectivityService extends IConnectivityManager.Stub 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 @@ public class ConnectivityService extends IConnectivityManager.Stub 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 223519ddb301..87b490d7ea25 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -246,6 +246,14 @@ public class DeviceIdleController extends SystemService 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 @@ public class DeviceIdleController extends SystemService 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 class DeviceIdleController extends SystemService 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 @@ public class DeviceIdleController extends SystemService } catch (IOException e) { } } - } private void readConfigFileLocked(XmlPullParser parser) { @@ -1639,7 +1653,10 @@ public class DeviceIdleController extends SystemService 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 759a4f380ba4..e7601c2ec93e 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 @@ public final class ActivityManagerService extends ActivityManagerNative } @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 e4650094be31..3cb98878ac86 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 @@ public final class ActivityStackSupervisor implements DisplayListener { } } - 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 @@ public final class ActivityStackSupervisor implements DisplayListener { // 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 @@ public final class ActivityStackSupervisor implements DisplayListener { } 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 @@ public final class ActivityStackSupervisor implements DisplayListener { // 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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 39914897a2a1..17ae6dce50d9 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.NetworkPolicy.WARNING_DISABLED; 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.LinkProperties; 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.text.format.Time; 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.SparseIntArray; 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.annotations.VisibleForTesting; 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { /** 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { // 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { updateRulesForUidStateChangeLocked(uid, oldUidState, uidState); if (mDeviceIdleMode && isProcStateAllowedWhileIdle(oldUidState) != isProcStateAllowedWhileIdle(uidState)) { - updateRulesForDeviceIdleLocked(); + updateRuleForDeviceIdleLocked(uid); } } } @@ -2039,7 +2039,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { updateRulesForUidStateChangeLocked(uid, oldUidState, ActivityManager.PROCESS_STATE_CACHED_EMPTY); if (mDeviceIdleMode) { - updateRulesForDeviceIdleLocked(); + updateRuleForDeviceIdleLocked(uid); } } } @@ -2086,7 +2086,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules); } + enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode); } @@ -2123,11 +2125,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } } + setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules); } @@ -2150,11 +2157,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { } } - 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * 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 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub { * 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 3e27c954ac42..f7f38dbdd697 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 @@ public class PackageManagerService extends IPackageManager.Stub { final int[] currentUserIds = UserManagerService.getInstance().getUserIds(); + boolean runtimePermissionsRevoked = false; int[] changedRuntimePermissionUserIds = EMPTY_INT_ARRAY; boolean changedInstallPermission = false; @@ -8480,6 +8481,17 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { 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 @@ public class PackageManagerService extends IPackageManager.Stub { } } + 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 3c2864853fab..2d8712375757 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 @@ public class DockedStackDividerController implements View.OnTouchListener, DimLa } 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 @@ public class DockedStackDividerController implements View.OnTouchListener, DimLa } 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 ca358b15bbb8..b409cea249c2 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 @@ public class TaskStack implements DimLayer.DimLayerUser { // 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 @@ public class TaskStack implements DimLayer.DimLayerUser { 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 @@ public class TaskStack implements DimLayer.DimLayerUser { } } + 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 @@ public class TaskStack implements DimLayer.DimLayerUser { } // 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 @@ public class TaskStack implements DimLayer.DimLayerUser { 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 @@ public class TaskStack implements DimLayer.DimLayerUser { && 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 0932f1570751..f571d9c3470e 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 class WindowManagerService extends IWindowManager.Stub } } + 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 8b37ec4cb8de..13e600ef30e7 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 @@ public class UsageStatsService extends SystemService implements mAppIdleParoled = paroled; if (DEBUG) Slog.d(TAG, "Changing paroled to " + mAppIdleParoled); if (paroled) { + postParoleEndTimeout(); + } else { mLastAppIdleParoledTime = checkAndGetTimeLocked(); postNextParoleTimeout(); } @@ -404,8 +406,6 @@ public class UsageStatsService extends SystemService implements 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 @@ public class UsageStatsService extends SystemService implements 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 b2dc29a90fb1..93b3f4f6710d 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.Looper; 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 final class BridgeContext extends Context { 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; |