Merge "Fix replacing window timeouts" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index e1569f1..e91d017 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6073,6 +6073,7 @@
field public static final int KEYGUARD_DISABLE_FEATURES_ALL = 2147483647; // 0x7fffffff
field public static final int KEYGUARD_DISABLE_FEATURES_NONE = 0; // 0x0
field public static final int KEYGUARD_DISABLE_FINGERPRINT = 32; // 0x20
+ field public static final int KEYGUARD_DISABLE_REMOTE_INPUT = 64; // 0x40
field public static final int KEYGUARD_DISABLE_SECURE_CAMERA = 2; // 0x2
field public static final int KEYGUARD_DISABLE_SECURE_NOTIFICATIONS = 4; // 0x4
field public static final int KEYGUARD_DISABLE_TRUST_AGENTS = 16; // 0x10
diff --git a/api/system-current.txt b/api/system-current.txt
index 55f8b6f..8781663 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6240,6 +6240,7 @@
field public static final int KEYGUARD_DISABLE_FEATURES_ALL = 2147483647; // 0x7fffffff
field public static final int KEYGUARD_DISABLE_FEATURES_NONE = 0; // 0x0
field public static final int KEYGUARD_DISABLE_FINGERPRINT = 32; // 0x20
+ field public static final int KEYGUARD_DISABLE_REMOTE_INPUT = 64; // 0x40
field public static final int KEYGUARD_DISABLE_SECURE_CAMERA = 2; // 0x2
field public static final int KEYGUARD_DISABLE_SECURE_NOTIFICATIONS = 4; // 0x4
field public static final int KEYGUARD_DISABLE_TRUST_AGENTS = 16; // 0x10
diff --git a/api/test-current.txt b/api/test-current.txt
index 1376ef1..410eb88 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -6078,6 +6078,7 @@
field public static final int KEYGUARD_DISABLE_FEATURES_ALL = 2147483647; // 0x7fffffff
field public static final int KEYGUARD_DISABLE_FEATURES_NONE = 0; // 0x0
field public static final int KEYGUARD_DISABLE_FINGERPRINT = 32; // 0x20
+ field public static final int KEYGUARD_DISABLE_REMOTE_INPUT = 64; // 0x40
field public static final int KEYGUARD_DISABLE_SECURE_CAMERA = 2; // 0x2
field public static final int KEYGUARD_DISABLE_SECURE_NOTIFICATIONS = 4; // 0x4
field public static final int KEYGUARD_DISABLE_TRUST_AGENTS = 16; // 0x10
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index e54edf2..43238ec 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5205,10 +5205,6 @@
} else {
Log.e(TAG, "Unable to setupGraphicsSupport due to missing code-cache directory");
}
-
- // Add the lib dir path to hardware renderer so that vulkan layers
- // can be searched for within that directory.
- ThreadedRenderer.setLibDir(data.info.getLibDir());
}
// Install the Network Security Config Provider. This must happen before the application
diff --git a/core/java/android/app/ApplicationLoaders.java b/core/java/android/app/ApplicationLoaders.java
index d89e186..c869944 100644
--- a/core/java/android/app/ApplicationLoaders.java
+++ b/core/java/android/app/ApplicationLoaders.java
@@ -65,6 +65,8 @@
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
+ setupVulkanLayerPath(pathClassloader, librarySearchPath);
+
mLoaders.put(zip, pathClassloader);
return pathClassloader;
}
@@ -76,6 +78,8 @@
}
}
+ private static native void setupVulkanLayerPath(ClassLoader classLoader, String librarySearchPath);
+
/**
* Adds a new path the classpath of the given loader.
* @throws IllegalStateException if the provided class loader is not a {@link PathClassLoader}.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 451acf3..f78ed1e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -2571,6 +2571,11 @@
public static final int KEYGUARD_DISABLE_FINGERPRINT = 1 << 5;
/**
+ * Disable text entry into notifications on secure keyguard screens (e.g. PIN/Pattern/Password).
+ */
+ public static final int KEYGUARD_DISABLE_REMOTE_INPUT = 1 << 6;
+
+ /**
* Disable all current and future keyguard customizations.
*/
public static final int KEYGUARD_DISABLE_FEATURES_ALL = 0x7fffffff;
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index 1cd2fb0..e650d95 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -252,17 +252,6 @@
}
/**
- * Sets the library directory to use as a search path for vulkan layers.
- *
- * @param libDir A directory that contains vulkan layers
- *
- * @hide
- */
- public static void setLibDir(String libDir) {
- ThreadedRenderer.setupVulkanLayerPath(libDir);
- }
-
- /**
* Creates a hardware renderer using OpenGL.
*
* @param translucent True if the surface is translucent, false otherwise
@@ -980,7 +969,6 @@
}
static native void setupShadersDiskCache(String cacheFile);
- static native void setupVulkanLayerPath(String layerPath);
private static native void nSetAtlas(long nativeProxy, GraphicBuffer buffer, long[] map);
private static native void nSetProcessStatsBuffer(long nativeProxy, int fd);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4e7d1914..77884f6 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8740,7 +8740,7 @@
* @param direction The direction of the focus
*/
public void addFocusables(ArrayList<View> views, @FocusDirection int direction) {
- addFocusables(views, direction, FOCUSABLES_TOUCH_MODE);
+ addFocusables(views, direction, isInTouchMode() ? FOCUSABLES_TOUCH_MODE : FOCUSABLES_ALL);
}
/**
@@ -8768,7 +8768,7 @@
return;
}
if ((focusableMode & FOCUSABLES_TOUCH_MODE) == FOCUSABLES_TOUCH_MODE
- && isInTouchMode() && !isFocusableInTouchMode()) {
+ && !isFocusableInTouchMode()) {
return;
}
views.add(this);
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 2b7afea..5554182 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -549,6 +549,7 @@
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
long capabilities = posixCapabilitiesAsBits(
+ OsConstants.CAP_IPC_LOCK,
OsConstants.CAP_KILL,
OsConstants.CAP_NET_ADMIN,
OsConstants.CAP_NET_BIND_SERVICE,
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 986a5fd..dd66b24 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -34,6 +34,7 @@
com_google_android_gles_jni_EGLImpl.cpp \
com_google_android_gles_jni_GLImpl.cpp.arm \
android_app_Activity.cpp \
+ android_app_ApplicationLoaders.cpp \
android_app_NativeActivity.cpp \
android_app_admin_SecurityLog.cpp \
android_opengl_EGL14.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index c2273d6..315887d 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -181,6 +181,7 @@
extern int register_android_app_backup_FullBackup(JNIEnv *env);
extern int register_android_app_Activity(JNIEnv *env);
extern int register_android_app_ActivityThread(JNIEnv *env);
+extern int register_android_app_ApplicationLoaders(JNIEnv *env);
extern int register_android_app_NativeActivity(JNIEnv *env);
extern int register_android_media_RemoteDisplay(JNIEnv *env);
extern int register_android_util_jar_StrictJarFile(JNIEnv* env);
@@ -1389,6 +1390,7 @@
REG_JNI(register_android_app_backup_FullBackup),
REG_JNI(register_android_app_Activity),
REG_JNI(register_android_app_ActivityThread),
+ REG_JNI(register_android_app_ApplicationLoaders),
REG_JNI(register_android_app_NativeActivity),
REG_JNI(register_android_util_jar_StrictJarFile),
REG_JNI(register_android_view_InputChannel),
diff --git a/core/jni/android_app_ApplicationLoaders.cpp b/core/jni/android_app_ApplicationLoaders.cpp
new file mode 100644
index 0000000..24ee959
--- /dev/null
+++ b/core/jni/android_app_ApplicationLoaders.cpp
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <nativehelper/ScopedUtfChars.h>
+#include <nativeloader/native_loader.h>
+#include <vulkan/vulkan_loader_data.h>
+
+#include "core_jni_helpers.h"
+
+static void setupVulkanLayerPath_native(JNIEnv* env, jobject clazz,
+ jobject classLoader, jstring librarySearchPath) {
+ ScopedUtfChars layerPathChars(env, librarySearchPath);
+ vulkan::LoaderData& loader_data = vulkan::LoaderData::GetInstance();
+ loader_data.layer_path = layerPathChars.c_str();
+ loader_data.app_namespace = android::FindNamespaceByClassLoader(env, classLoader);
+}
+
+static const JNINativeMethod g_methods[] = {
+ { "setupVulkanLayerPath", "(Ljava/lang/ClassLoader;Ljava/lang/String;)V",
+ reinterpret_cast<void*>(setupVulkanLayerPath_native) },
+};
+
+static const char* const kApplicationLoadersName = "android/app/ApplicationLoaders";
+
+namespace android
+{
+
+int register_android_app_ApplicationLoaders(JNIEnv* env) {
+ return RegisterMethodsOrDie(env, kApplicationLoadersName, g_methods, NELEM(g_methods));
+}
+
+} // namespace android
diff --git a/core/jni/android_view_ThreadedRenderer.cpp b/core/jni/android_view_ThreadedRenderer.cpp
index 650a0fc..5b4bfe9 100644
--- a/core/jni/android_view_ThreadedRenderer.cpp
+++ b/core/jni/android_view_ThreadedRenderer.cpp
@@ -28,7 +28,6 @@
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <EGL/egl_cache.h>
-#include <vulkan/vulkan_loader_data.h>
#include <utils/Looper.h>
#include <utils/RefBase.h>
@@ -50,7 +49,6 @@
#include <renderthread/RenderProxy.h>
#include <renderthread/RenderTask.h>
#include <renderthread/RenderThread.h>
-#include <Vector.h>
namespace android {
@@ -718,18 +716,6 @@
}
// ----------------------------------------------------------------------------
-// Layers
-// ----------------------------------------------------------------------------
-
-static void android_view_ThreadedRenderer_setupVulkanLayerPath(JNIEnv* env, jobject clazz,
- jstring layerPath) {
-
- const char* layerArray = env->GetStringUTFChars(layerPath, NULL);
- vulkan::LoaderData::GetInstance().layer_path = layerArray;
- env->ReleaseStringUTFChars(layerPath, layerArray);
-}
-
-// ----------------------------------------------------------------------------
// JNI Glue
// ----------------------------------------------------------------------------
@@ -771,8 +757,6 @@
{ "nDumpProfileData", "([BLjava/io/FileDescriptor;)V", (void*) android_view_ThreadedRenderer_dumpProfileData },
{ "setupShadersDiskCache", "(Ljava/lang/String;)V",
(void*) android_view_ThreadedRenderer_setupShadersDiskCache },
- { "setupVulkanLayerPath", "(Ljava/lang/String;)V",
- (void*) android_view_ThreadedRenderer_setupVulkanLayerPath },
{ "nAddRenderNode", "(JJZ)V", (void*) android_view_ThreadedRenderer_addRenderNode},
{ "nRemoveRenderNode", "(JJ)V", (void*) android_view_ThreadedRenderer_removeRenderNode},
{ "nDrawRenderNode", "(JJ)V", (void*) android_view_ThreadedRendererd_drawRenderNode},
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2a83d88..e64d905 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2476,4 +2476,9 @@
<!-- True if the device supports persisting security logs across reboots. -->
<bool name="config_supportPreRebootSecurityLogs">false</bool>
+
+ <!-- Default files to pin via Pinner Service -->
+ <string-array translatable="false" name="config_defaultPinnerServiceFiles">
+ </string-array>
+
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7ed293f..ac36a2f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2587,4 +2587,8 @@
<java-symbol type="string" name="config_tvRemoteServicePackage" />
<java-symbol type="bool" name="config_supportPreRebootSecurityLogs" />
+
+ <!-- Pinner Service -->
+ <java-symbol type="array" name="config_defaultPinnerServiceFiles" />
+
</resources>
diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd
index de38f3d..6835beb 100644
--- a/docs/html/develop/index.jd
+++ b/docs/html/develop/index.jd
@@ -9,7 +9,7 @@
excludeFromSuggestions=true
@jd:body
-<section class="dac-expand dac-hero dac-section-light" style="background:#FFE57F">
+<section class="dac-expand dac-hero dac-section-light">
<div class="wrap">
<div class="cols dac-hero-content">
<div class="col-1of2 col-push-1of2 dac-hero-figure">
@@ -19,14 +19,14 @@
frameborder="0" allowfullscreen=""
style="float: right;"></iframe>
-->
- <a href="{@docRoot}sdk/index.html">
+ <a href="{@docRoot}studio/index.html">
<img class="dac-hero-image" src="{@docRoot}images/tools/studio/studio-feature-instant-run_2x.png" />
</a>
</div>
<div class="col-1of2 col-pull-1of2">
<h1 class="dac-hero-title">
- <a style="color:inherit" href="{@docRoot}sdk/index.html">
- Android Studio 2.0,<br>now available!</a></h1>
+ <a style="color:inherit" href="{@docRoot}studio/index.html">
+ Android Studio 2.1,<br>now available!</a></h1>
<p class="dac-hero-description">
The latest version of Android Studio is the biggest update yet.
It includes new features like <strong>Instant Run</strong>, which
@@ -35,7 +35,7 @@
</p>
<div class="cols">
<div class="col-1of2">
- <a class="dac-hero-cta" href="{@docRoot}sdk/index.html">
+ <a class="dac-hero-cta" href="{@docRoot}studio/index.html">
<span class="dac-sprite dac-auto-chevron"></span>
Get Android Studio
</a><br>
diff --git a/docs/html/distribute/essentials/quality/billions.jd b/docs/html/distribute/essentials/quality/billions.jd
index 58f15a3..7042143 100644
--- a/docs/html/distribute/essentials/quality/billions.jd
+++ b/docs/html/distribute/essentials/quality/billions.jd
@@ -585,6 +585,16 @@
Implementing a Preferences Activity</a>.</li>
</ul>
+
+
+<h3 class="rel-resources clearfloat">Related resources</h3>
+<div class="resource-widget resource-flow-layout col-13"
+ data-query="collection:distribute/essentials/billionsquality/cost"
+ data-sortOrder="-timestamp"
+ data-cardSizes="6x3"
+ data-maxResults="6"></div>
+
+
<!-- consumption -->
<div class="headerLine">
<h2 id="consumption">Battery Consumption</h2>
diff --git a/docs/html/guide/topics/manifest/permission-element.jd b/docs/html/guide/topics/manifest/permission-element.jd
index 4bb5f6a..d8dbf40 100644
--- a/docs/html/guide/topics/manifest/permission-element.jd
+++ b/docs/html/guide/topics/manifest/permission-element.jd
@@ -10,70 +10,80 @@
android:<a href="#label">label</a>="<i>string resource</i>"
android:<a href="#nm">name</a>="<i>string</i>"
android:<a href="#pgroup">permissionGroup</a>="<i>string</i>"
- android:<a href="#plevel">protectionLevel</a>=["normal" | "dangerous" |
+ android:<a href="#plevel">protectionLevel</a>=["normal" | "dangerous" |
"signature" | "signatureOrSystem"] /></pre></dd>
<dt>contained in:</dt>
-<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code></dd>
+<dd><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"
+ ><manifest></a></code></dd>
<dt>description:</dt>
-<dd itemprop="description">Declares a security permission that can be used to limit access
-to specific components or features of this or other applications.
-See the <a href="{@docRoot}guide/topics/manifest/manifest-intro.html#perms">Permissions</a>
-section in the introduction,
-and the <a href="{@docRoot}guide/topics/security/security.html">Security and Permissions</a>
-document for more information on how permissions work.</dd>
+<dd itemprop="description">Declares a security permission that can be used to
+limit access to specific components or features of this or other applications.
+See the <a href="{@docRoot}guide/topics/manifest/manifest-intro.html#perms"
+>Permissions</a> section in the introduction, and the <a
+href="{@docRoot}guide/topics/security/security.html">Security and
+Permissions</a> document for more information on how permissions work.</dd>
<dt>attributes:</dt>
<dd><dl class="attr">
<dt><a name="desc"></a>{@code android:description}</dt>
-<dd>A user-readable description of the permission, longer and more
-informative than the label. It may be displayed to explain the
-permission to the user — for example, when the user is asked
+<dd>A user-readable description of the permission, longer and more
+informative than the label. It may be displayed to explain the
+permission to the user — for example, when the user is asked
whether to grant the permission to another application.
<p>
-This attribute must be set as a reference to a string resource;
+This attribute must be set as a reference to a string resource;
unlike the {@code label} attribute, it cannot be a raw string.
</p></dd>
<dt><a name="icon"></a>{@code android:icon}</dt>
-<dd>A reference to a drawable resource for an icon that represents the
+<dd>A reference to a drawable resource for an icon that represents the
permission.</dd>
<dt><a name="label"></a>{@code android:label}</dt>
-<dd>A name for the permission, one that can be displayed to users.
+<dd>A name for the permission, one that can be displayed to users.
<p>
-As a convenience, the label can be directly set
-as a raw string while you're developing the application. However,
-when the application is ready to be published, it should be set as a
-reference to a string resource, so that it can be localized like other
+As a convenience, the label can be directly set
+as a raw string while you're developing the application. However,
+when the application is ready to be published, it should be set as a
+reference to a string resource, so that it can be localized like other
strings in the user interface.
</p></dd>
<dt><a name="nm"></a>{@code android:name}</dt>
-<dd>The name of the permission. This is the name that will be used in
-code to refer to the permission — for example, in a
-<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code> element and the
+<dd>The name of the permission. This is the name that will be used in
+code to refer to the permission — for example, in a
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"
+ ><uses-permission></a></code> element and the
{@code permission} attributes of application components.
-<p>
-The name must be unique, so it should use Java-style scoping —
-for example, "{@code com.example.project.PERMITTED_ACTION}".
-</p></dd>
+
+<p class="note">
+ <strong>Note:</strong> The system does not allow multiple packages to declare
+ a permission with the same name, unless all the packages are signed with the
+ same certificate. If a package declares a permission, the system does not permit
+ the user to install other packages with the same permission name, unless
+ those packages are signed with the same certificate as the first package. To
+ avoid naming collisions, we recommend using reverse-domain-style naming for custom
+ permissions, for example <code>com.example.myapp.ENGAGE_HYPERSPACE</code>.
+</p>
+</dd>
<dt><a name="pgroup"></a>{@code android:permissionGroup}</dt>
-<dd>Assigns this permission to a group. The value of this attribute is
-the name of the group, which must be declared with the
-<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html"><permission-group></a></code> element in this
+<dd>Assigns this permission to a group. The value of this attribute is
+the name of the group, which must be declared with the
+<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html"
+ ><permission-group></a></code> element in this
or another application. If this attribute is not set, the permission
does not belong to a group.</dd>
<dt><a name="plevel"></a>{@code android:protectionLevel}</dt>
<dd>Characterizes the potential risk implied in the permission and
indicates the procedure the system should follow when determining
-whether or not to grant the permission to an application requesting it.
+whether or not to grant the permission to an application requesting it.
The value can be set to one of the following strings:
<table>
@@ -82,9 +92,9 @@
<th>Meaning</th>
</tr><tr>
<td>"{@code normal}"</td>
- <td>The default value. A lower-risk permission that gives requesting
- applications access to isolated application-level features, with
- minimal risk to other applications, the system, or the user.
+ <td>The default value. A lower-risk permission that gives requesting
+ applications access to isolated application-level features, with
+ minimal risk to other applications, the system, or the user.
The system automatically grants this type
of permission to a requesting application at installation, without
asking for the user's explicit approval (though the user always
@@ -109,11 +119,11 @@
asking for the user's explicit approval.
</tr><tr>
<td>"{@code signatureOrSystem}"</td>
- <td>A permission that the system grants only to applications that are
+ <td>A permission that the system grants only to applications that are
in the Android system image <em>or</em> that are signed with the same
- certificate as the application that declared the permission. Please avoid using this
- option, as the {@code signature} protection level should be sufficient
- for most needs and works regardless of exactly where applications are
+ certificate as the application that declared the permission. Please avoid using this
+ option, as the {@code signature} protection level should be sufficient
+ for most needs and works regardless of exactly where applications are
installed. The "{@code signatureOrSystem}"
permission is used for certain special situations where multiple
vendors have applications built into a system image and need
diff --git a/docs/html/guide/topics/security/permissions.jd b/docs/html/guide/topics/security/permissions.jd
index f7f70b3..e7bf760 100644
--- a/docs/html/guide/topics/security/permissions.jd
+++ b/docs/html/guide/topics/security/permissions.jd
@@ -18,6 +18,7 @@
</li>
<li><a href="#defining">Defining and Enforcing Permissions</a>
<ol>
+ <li><a href="#custom-recommendations">Custom permission recommendations</a></li>
<li><a href="#manifest">...in AndroidManifest.xml</a></li>
<li><a href="#broadcasts">...when Sending Broadcasts</a></li>
<li><a href="#enforcement">Other Permission Enforcement</a></li>
@@ -540,17 +541,19 @@
<a name="declaring"></a>
<h2 id="defining">Defining and Enforcing Permissions</h2>
-<p>To enforce your own permissions, you must first declare them in your
-<code>AndroidManifest.xml</code> using one or more
-<code>{@link android.R.styleable#AndroidManifestPermission <permission>}</code>
-tags.</p>
+<p>
+ To enforce your own permissions, you must first declare them in your
+ <code>AndroidManifest.xml</code> using one or more <a href=
+ "{@docRoot}guide/topics/manifest/permission-element.html"><code><permission></code></a>
+ elements.
+</p>
<p>For example, an application that wants to control who can start one
of its activities could declare a permission for this operation as follows:</p>
<pre><manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.me.app.myapp" >
- <permission android:name="com.me.app.myapp.permission.DEADLY_ACTIVITY"
+ package="com.example.myapp" >
+ <permission android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
android:label="@string/permlab_deadlyActivity"
android:description="@string/permdesc_deadlyActivity"
android:permissionGroup="android.permission-group.COST_MONEY"
@@ -558,50 +561,65 @@
...
</manifest></pre>
+<p class="note">
+ <strong>Note:</strong> The system does not allow multiple packages to declare
+ a permission with the same name, unless all the packages are signed with the
+ same certificate. If a package declares a permission, the system does not permit
+ the user to install other packages with the same permission name, unless
+ those packages are signed with the same certificate as the first package. To
+ avoid naming collisions, we recommend using reverse-domain-style naming for custom
+ permissions, for example <code>com.example.myapp.ENGAGE_HYPERSPACE</code>.
+</p>
+
<p>The {@link android.R.styleable#AndroidManifestPermission_protectionLevel
-<protectionLevel>} attribute is required, telling the system how the
+protectionLevel} attribute is required, telling the system how the
user is to be informed of applications requiring the permission, or who is
allowed to hold that permission, as described in the linked documentation.</p>
-<p>The {@link android.R.styleable#AndroidManifestPermission_permissionGroup
-<permissionGroup>} attribute is optional, and only used to help the system display
-permissions to the user. You will usually want to set this to either a standard
-system group (listed in {@link android.Manifest.permission_group
-android.Manifest.permission_group}) or in more rare cases to one defined by
-yourself. It is preferred to use an existing group, as this simplifies the
-permission UI shown to the user.</p>
+<p>
+ The <a href=
+ "{@docRoot}guide/topics/manifest/permission-group-element.html"
+ ><code>android:permissionGroup</code></a>
+ attribute is optional, and only used to help the system display permissions
+ to the user. In most cases you will want to set this to a standard system
+ group (listed in {@link android.Manifest.permission_group
+ android.Manifest.permission_group}), although you can define a group yourself.
+ It is preferable to use an existing group, as this simplifies the
+ permission UI shown to the user.
+</p>
-<p>Note that both a label and description should be supplied for the
-permission. These are string resources that can be displayed to the user when
+<p>You need to supply both a label and description for the
+permission. These are string resources that the user can see when
they are viewing a list of permissions
(<code>{@link android.R.styleable#AndroidManifestPermission_label android:label}</code>)
or details on a single permission (
<code>{@link android.R.styleable#AndroidManifestPermission_description android:description}</code>).
-The label should be short, a few words
+The label should be short; a few words
describing the key piece of functionality the permission is protecting. The
-description should be a couple sentences describing what the permission allows
-a holder to do. Our convention for the description is two sentences, the first
-describing the permission, the second warning the user of what bad things
-can happen if an application is granted the permission.</p>
+description should be a couple of sentences describing what the permission allows
+a holder to do. Our convention is a two-sentence description:
+the first sentence describes the permission, and the second sentence warns the
+user of the type of things that can go wrong if an application is granted the
+permission.</p>
<p>Here is an example of a label and description for the CALL_PHONE
permission:</p>
<pre>
- <string name="permlab_callPhone">directly call phone numbers</string>
- <string name="permdesc_callPhone">Allows the application to call
- phone numbers without your intervention. Malicious applications may
- cause unexpected calls on your phone bill. Note that this does not
- allow the application to call emergency numbers.</string>
+<string name="permlab_callPhone">directly call phone numbers</string>
+<string name="permdesc_callPhone">Allows the application to call
+ phone numbers without your intervention. Malicious applications may
+ cause unexpected calls on your phone bill. Note that this does not
+ allow the application to call emergency numbers.</string>
</pre>
-<p>You can look at the permissions currently defined in the system with the
+<p>You can view at the permissions currently defined in the system using the
Settings app and the shell command <code>adb shell pm list permissions</code>.
-To use the Settings app, go to Settings > Applications. Pick an app and
+To use the Settings app, go to <b>Settings</b> > <b>Applications</b>. Pick an app and
scroll down to see the permissions that the app uses. For developers, the adb '-s'
option displays the permissions in a form similar to how the user will see them:</p>
-<pre>
+<pre class="no-pretty-print">
$ adb shell pm list permissions -s
All Permissions:
@@ -615,14 +633,53 @@
...</pre>
+<h3 id="custom-recommendations">
+ Custom permission recommendations
+</h3>
+
+<p>
+ Apps can define their own custom permissions and request custom permissions
+ from other apps by defining <a href=
+ "{@docRoot}guide/topics/manifest/uses-permission-element.html"><code
+ ><uses-permission></code></a> elements.
+ However, you should carefully assess whether it is necessary for your app to
+ do so.
+</p>
+
+<ul>
+ <li>If you are designing a suite of apps that expose functionality to one
+ another, try to design the apps so that each permission is defined only once.
+ You must do this if the apps are not all signed with the same certificate.
+ Even if the apps are all signed with the same certificate, it's a
+ best practice to define each permission once only.
+ </li>
+
+ <li>If the functionality is only available to apps signed with the same
+ signature as the providing app, you may be able to avoid defining custom
+ permissions by using signature checks. When one of your apps makes a request
+ of another of your apps, the second app can verify that both apps are signed
+ with the same certificate before complying with the request.
+ </li>
+
+ <li>If you are developing a suite of apps runs only on your own
+ devices, you should develop and install a package that
+ manages permissions for all the apps in the suite. This package does not need
+ to provide any services itself. It just declares all the permissions, and the
+ other apps in the suite request those permissions with the <a href=
+ "{@docRoot}guide/topics/manifest/uses-permission-element.html"><code
+ ><uses-permission></code></a>
+ element.
+ </li>
+</ul>
+
<a name="manifest"></a>
<h3>Enforcing Permissions in AndroidManifest.xml</h3>
-<p>High-level permissions restricting access to entire components of the
-system or application can be applied through your
-<code>AndroidManifest.xml</code>. All that this requires is including an {@link
+<p>TYou can apply high-level permissions restricting access to entire components
+of the system or application through your
+<code>AndroidManifest.xml</code>. To do this, include an {@link
android.R.attr#permission android:permission} attribute on the desired
-component, naming the permission that will be used to control access to
+component, naming the permission that controls access to
it.</p>
<p><strong>{@link android.app.Activity}</strong> permissions
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index cf6fb97..04e7a3d 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -375,7 +375,7 @@
"distribute/essentials/quality/tv.html",
"distribute/essentials/quality/wear.html",
"distribute/essentials/quality/auto.html",
- "https://developers.google.com/edu/guidelines"
+ "distribute/essentials/quality/billions.html"
]
},
"distribute/essentials/zhcn": {
@@ -506,7 +506,7 @@
"distribute/essentials/quality/wear.html",
"distribute/essentials/quality/tv.html",
"distribute/essentials/quality/auto.html",
- "https://developers.google.com/edu/guidelines"
+ "distribute/essentials/quality/billions.html"
]
},
"distribute/essentials/tools": {
@@ -1007,6 +1007,44 @@
"google/play/filters.html"
]
},
+ "distribute/essentials/billionsquality/connectivity": {
+ "title": "",
+ "resources": [
+ "training/basics/network-ops/managing.html",
+ "training/monitoring-device-state/connectivity-monitoring.html",
+ "guide/topics/providers/content-providers.html"
+ ]
+ },
+ "distribute/essentials/billionsquality/capability": {
+ "title": "",
+ "resources": [
+ "guide/practices/screens_support.html",
+ "training/multiscreen/screendensities.html",
+ "training/articles/memory.html"
+ ]
+ },
+ "distribute/essentials/billionsquality/cost": {
+ "title": "",
+ "resources": [
+ "https://medium.com/@wkalicinski/smallerapk-part-6-image-optimization-zopfli-webp-4c462955647d#.23hlddo3x",
+ "training/basics/network-ops/managing.html"
+ ]
+ },
+ "distribute/essentials/billionsquality/consumption": {
+ "title": "",
+ "resources": [
+ "training/efficient-downloads/efficient-network-access.html",
+ "training/monitoring-device-state/index.html"
+ ]
+ },
+ "distribute/essentials/billionsquality/content": {
+ "title": "",
+ "resources": [
+ "training/material/animations.html#Touch",
+ "training/articles/perf-anr.html",
+ "training/improving-layouts/index.html"
+ ]
+ },
"distribute/essentials/tabletguidelines": {
"title": "",
"resources": [
diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js
index d176883..685394f 100644
--- a/docs/html/jd_extras.js
+++ b/docs/html/jd_extras.js
@@ -32,6 +32,17 @@
"type":"medium"
},
{
+ "title":"SmallerAPK, Part 6: Image optimization, Zopfli & WebP",
+ "category":"",
+ "summary":"Series of posts on minimizing your APK size.",
+ "url":"https://medium.com/@wkalicinski/smallerapk-part-6-image-optimization-zopfli-webp-4c462955647d#.23hlddo3x",
+ "group":"",
+ "keywords": [],
+ "tags": [],
+ "image":"https://cdn-images-1.medium.com/max/2000/1*chMiA9mGa_FBUOoesHHk3Q.png",
+ "type":"medium"
+ },
+ {
"title":"Measure your app’s user acquisition channels",
"titleFriendly":"",
"summary":"Get details on how to use the Developer Console User Acquisitions reports to discover where your users come from.",
@@ -999,6 +1010,19 @@
"lang": "en",
"group": "",
"tags": [],
+ "url": "training/material/animations.html#Touch",
+ "timestamp": 1194884220000,
+ "image": null,
+ "title": "Customize Touch Feedback",
+ "summary": "Provide visual confirmation when users interact with your UI.",
+ "keywords": [],
+ "type": "develop",
+ "category": "guide"
+ },
+ {
+ "lang": "en",
+ "group": "",
+ "tags": [],
"url": "guide/topics/manifest/uses-feature-element.html#testing",
"timestamp": 1194884220000,
"image": null,
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 596e5a8..f49594c 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -46,6 +46,7 @@
import android.os.DropBoxManager;
import android.os.Environment;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
@@ -199,6 +200,12 @@
@GuardedBy("mLock")
private SettingsRegistry mSettingsRegistry;
+ @GuardedBy("mLock")
+ private HandlerThread mHandlerThread;
+
+ @GuardedBy("mLock")
+ private Handler mBackgroundHandler;
+
// We have to call in the user manager with no lock held,
private volatile UserManager mUserManager;
@@ -244,6 +251,10 @@
synchronized (mLock) {
mUserManager = UserManager.get(getContext());
mPackageManager = AppGlobals.getPackageManager();
+ mHandlerThread = new HandlerThread(LOG_TAG,
+ Process.THREAD_PRIORITY_BACKGROUND);
+ mHandlerThread.start();
+ mBackgroundHandler = new Handler(mHandlerThread.getLooper());
mSettingsRegistry = new SettingsRegistry();
}
registerBroadcastReceivers();
@@ -1669,7 +1680,7 @@
if (mSettingsStates.get(key) == null) {
final int maxBytesPerPackage = getMaxBytesPerPackageForType(getTypeFromKey(key));
SettingsState settingsState = new SettingsState(mLock, getSettingsFile(key), key,
- maxBytesPerPackage);
+ maxBytesPerPackage, mBackgroundHandler);
mSettingsStates.put(key, settingsState);
}
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 2de0618c..1e02747 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -95,7 +95,7 @@
private final Object mLock;
- private final Handler mHandler = new MyHandler();
+ private final Handler mHandler;
@GuardedBy("mLock")
private final ArrayMap<String, Setting> mSettings = new ArrayMap<>();
@@ -134,13 +134,15 @@
@GuardedBy("mLock")
private long mNextId;
- public SettingsState(Object lock, File file, int key, int maxBytesPerAppPackage) {
+ public SettingsState(Object lock, File file, int key, int maxBytesPerAppPackage,
+ Handler handler) {
// It is important that we use the same lock as the settings provider
// to ensure multiple mutations on this state are atomicaly persisted
// as the async persistence should be blocked while we make changes.
mLock = lock;
mStatePersistFile = file;
mKey = key;
+ mHandler = handler;
if (maxBytesPerAppPackage == MAX_BYTES_PER_APP_PACKAGE_LIMITED) {
mMaxBytesPerAppPackage = maxBytesPerAppPackage;
mPackageToMemoryUsage = new ArrayMap<>();
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
index 3f9ffa1..53c2958 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsStateTest.java
@@ -15,6 +15,7 @@
*/
package com.android.providers.settings;
+import android.os.Handler;
import android.test.AndroidTestCase;
import android.util.Xml;
@@ -126,7 +127,7 @@
final Object lock = new Object();
final SettingsState ssWriter = new SettingsState(lock, file, 1,
- SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED);
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, new Handler());
ssWriter.setVersionLocked(SettingsState.SETTINGS_VERSOIN_NEW_ENCODING);
ssWriter.insertSettingLocked("k1", "\u0000", "package");
@@ -138,7 +139,7 @@
}
final SettingsState ssReader = new SettingsState(lock, file, 1,
- SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED);
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, new Handler());
synchronized (lock) {
assertEquals("\u0000", ssReader.getSettingLocked("k1").getValue());
assertEquals("abc", ssReader.getSettingLocked("k2").getValue());
@@ -165,7 +166,7 @@
os.close();
final SettingsState ss = new SettingsState(lock, file, 1,
- SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED);
+ SettingsState.MAX_BYTES_PER_APP_PACKAGE_UNLIMITED, new Handler());
synchronized (lock) {
SettingsState.Setting s;
s = ss.getSettingLocked("k0");
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index a5f3e77..0f356e0 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -107,6 +107,7 @@
private boolean mFinishedOnStartup;
private boolean mIgnoreAltTabRelease;
private boolean mIsVisible;
+ private boolean mReceivedNewIntent;
// Top level views
private RecentsView mRecentsView;
@@ -120,6 +121,9 @@
private int mFocusTimerDuration;
private DozeTrigger mIterateTrigger;
private final UserInteractionEvent mUserInteractionEvent = new UserInteractionEvent();
+ private final Runnable mSendEnterWindowAnimationCompleteRunnable = () -> {
+ EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+ };
/**
* A common Runnable to finish Recents by launching Home with an animation depending on the
@@ -342,6 +346,7 @@
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
+ mReceivedNewIntent = true;
// Reload the stack view
reloadStackView();
@@ -364,7 +369,7 @@
RecentsActivityLaunchState launchState = config.getLaunchState();
if (!loadPlan.hasTasks()) {
loader.preloadTasks(loadPlan, launchState.launchedToTaskId,
- launchState.launchedFromHome);
+ !launchState.launchedFromHome);
}
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
@@ -419,7 +424,16 @@
@Override
public void onEnterAnimationComplete() {
super.onEnterAnimationComplete();
- EventBus.getDefault().send(new EnterRecentsWindowAnimationCompletedEvent());
+
+ // Workaround for b/28705801, on first docking, we may receive the enter animation callback
+ // before the first layout, so in such cases, send the event on the next frame after all
+ // the views are laid out and attached (and registered to the EventBus).
+ mHandler.removeCallbacks(mSendEnterWindowAnimationCompleteRunnable);
+ if (!mReceivedNewIntent) {
+ mHandler.post(mSendEnterWindowAnimationCompleteRunnable);
+ } else {
+ mSendEnterWindowAnimationCompleteRunnable.run();
+ }
}
@Override
@@ -453,7 +467,8 @@
RecentsActivityLaunchState launchState = config.getLaunchState();
RecentsTaskLoader loader = Recents.getTaskLoader();
RecentsTaskLoadPlan loadPlan = loader.createLoadPlan(this);
- loader.preloadTasks(loadPlan, -1 /* runningTaskId */, false /* isHomeStackVisible */);
+ loader.preloadTasks(loadPlan, -1 /* runningTaskId */,
+ false /* includeFrontMostExcludedTask */);
RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options();
loadOpts.numVisibleTasks = launchState.launchedNumVisibleTasks;
@@ -477,6 +492,7 @@
// Notify that recents is now hidden
mIsVisible = false;
+ mReceivedNewIntent = false;
EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false));
MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
index 297dec9..611f9f2 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
@@ -112,7 +112,7 @@
// Load the next task only if we aren't svelte
RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
- loader.preloadTasks(plan, -1, true /* isHomeStackVisible */);
+ loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */);
RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
// This callback is made when a new activity is launched and the old one is paused
// so ignore the current activity and try and preload the thumbnail for the
@@ -189,7 +189,7 @@
// We can use a new plan since the caches will be the same.
RecentsTaskLoader loader = Recents.getTaskLoader();
RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
- loader.preloadTasks(plan, -1, true /* isHomeStackVisible */);
+ loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */);
RecentsTaskLoadPlan.Options launchOpts = new RecentsTaskLoadPlan.Options();
launchOpts.numVisibleTasks = loader.getIconCacheSize();
launchOpts.numVisibleTaskThumbnails = loader.getThumbnailCacheSize();
@@ -366,8 +366,8 @@
ActivityManager.RunningTaskInfo runningTask = ssp.getRunningTask();
RecentsTaskLoader loader = Recents.getTaskLoader();
sInstanceLoadPlan = loader.createLoadPlan(mContext);
- sInstanceLoadPlan.preloadRawTasks(isHomeStackVisible.value);
- loader.preloadTasks(sInstanceLoadPlan, runningTask.id, isHomeStackVisible.value);
+ sInstanceLoadPlan.preloadRawTasks(!isHomeStackVisible.value);
+ loader.preloadTasks(sInstanceLoadPlan, runningTask.id, !isHomeStackVisible.value);
TaskStack stack = sInstanceLoadPlan.getTaskStack();
if (stack.getTaskCount() > 0) {
// Only preload the icon (but not the thumbnail since it may not have been taken for
@@ -401,7 +401,7 @@
SystemServicesProxy ssp = Recents.getSystemServices();
RecentsTaskLoader loader = Recents.getTaskLoader();
RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
- loader.preloadTasks(plan, -1, true /* isHomeStackVisible */);
+ loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */);
TaskStack focusedStack = plan.getTaskStack();
// Return early if there are no tasks in the focused stack
@@ -453,7 +453,7 @@
SystemServicesProxy ssp = Recents.getSystemServices();
RecentsTaskLoader loader = Recents.getTaskLoader();
RecentsTaskLoadPlan plan = loader.createLoadPlan(mContext);
- loader.preloadTasks(plan, -1, true /* isHomeStackVisible */);
+ loader.preloadTasks(plan, -1, false /* includeFrontMostExcludedTask */);
TaskStack focusedStack = plan.getTaskStack();
// Return early if there are no tasks in the focused stack
@@ -818,7 +818,7 @@
sInstanceLoadPlan = loader.createLoadPlan(mContext);
}
if (mLaunchedWhileDocking || mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
- loader.preloadTasks(sInstanceLoadPlan, runningTask.id, isHomeStackVisible);
+ loader.preloadTasks(sInstanceLoadPlan, runningTask.id, !isHomeStackVisible);
}
TaskStack stack = sInstanceLoadPlan.getTaskStack();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index 08b52d9..62c1945 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -253,11 +253,12 @@
/**
* Returns a list of the recents tasks.
*
- * @param isHomeStackVisible whether or not the home stack is currently visible. If it is
- * visible, then we ignore all excluded tasks (even the first one).
+ * @param includeFrontMostExcludedTask if set, will ensure that the front most excluded task
+ * will be visible, otherwise no excluded tasks will be
+ * visible.
*/
public List<ActivityManager.RecentTaskInfo> getRecentTasks(int numLatestTasks, int userId,
- boolean isHomeStackVisible, ArraySet<Integer> quietProfileIds) {
+ boolean includeFrontMostExcludedTask, ArraySet<Integer> quietProfileIds) {
if (mAm == null) return null;
// If we are mocking, then create some recent tasks
@@ -295,13 +296,16 @@
// Remove home/recents/excluded tasks
int minNumTasksToQuery = 10;
int numTasksToQuery = Math.max(minNumTasksToQuery, numLatestTasks);
- List<ActivityManager.RecentTaskInfo> tasks = mAm.getRecentTasksForUser(numTasksToQuery,
- ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
+ int flags = ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS |
ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK |
ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS |
ActivityManager.RECENT_IGNORE_UNAVAILABLE |
- ActivityManager.RECENT_INCLUDE_PROFILES |
- ActivityManager.RECENT_WITH_EXCLUDED, userId);
+ ActivityManager.RECENT_INCLUDE_PROFILES;
+ if (includeFrontMostExcludedTask) {
+ flags |= ActivityManager.RECENT_WITH_EXCLUDED;
+ }
+ List<ActivityManager.RecentTaskInfo> tasks = mAm.getRecentTasksForUser(numTasksToQuery,
+ flags, userId);
// Break early if we can't get a valid set of tasks
if (tasks == null) {
@@ -316,18 +320,20 @@
// NOTE: The order of these checks happens in the expected order of the traversal of the
// tasks
- // Check the first non-recents task, include this task even if it is marked as excluded
- // from recents if we are currently in the app. In other words, only remove excluded
- // tasks if it is not the first active task, and not in the blacklist.
+ // Remove the task if it is blacklisted
+ if (sRecentsBlacklist.contains(t.realActivity.getClassName())) {
+ iter.remove();
+ }
+
+ // Remove the task if it is marked as excluded, unless it is the first most task and we
+ // are requested to include it
boolean isExcluded = (t.baseIntent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
== Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
- boolean isBlackListed = sRecentsBlacklist.contains(t.realActivity.getClassName());
- // Filter out recent tasks from managed profiles which are in quiet mode.
isExcluded |= quietProfileIds.contains(t.userId);
- if (isBlackListed || (isExcluded && (isHomeStackVisible || !isFirstValidTask))) {
+ if (isExcluded && (!isFirstValidTask || !includeFrontMostExcludedTask)) {
iter.remove();
- continue;
}
+
isFirstValidTask = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 251ad71..1278b73 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -100,12 +100,12 @@
* An optimization to preload the raw list of tasks. The raw tasks are saved in least-recent
* to most-recent order.
*/
- public synchronized void preloadRawTasks(boolean isHomeStackVisible) {
+ public synchronized void preloadRawTasks(boolean includeFrontMostExcludedTask) {
int currentUserId = UserHandle.USER_CURRENT;
updateCurrentQuietProfilesCache(currentUserId);
SystemServicesProxy ssp = Recents.getSystemServices();
mRawTasks = ssp.getRecentTasks(ActivityManager.getMaxRecentTasksStatic(),
- currentUserId, isHomeStackVisible, mCurrentQuietProfiles);
+ currentUserId, includeFrontMostExcludedTask, mCurrentQuietProfiles);
// Since the raw tasks are given in most-recent to least-recent order, we need to reverse it
Collections.reverse(mRawTasks);
@@ -121,11 +121,11 @@
* - least-recent to most-recent freeform tasks
*/
public synchronized void preloadPlan(RecentsTaskLoader loader, int runningTaskId,
- boolean isHomeStackVisible) {
+ boolean includeFrontMostExcludedTask) {
Resources res = mContext.getResources();
ArrayList<Task> allTasks = new ArrayList<>();
if (mRawTasks == null) {
- preloadRawTasks(isHomeStackVisible);
+ preloadRawTasks(includeFrontMostExcludedTask);
}
SparseArray<Task.TaskKey> affiliatedTasks = new SparseArray<>();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
index 9460b64..ca59831 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java
@@ -334,8 +334,8 @@
/** Preloads recents tasks using the specified plan to store the output. */
public void preloadTasks(RecentsTaskLoadPlan plan, int runningTaskId,
- boolean isHomeStackVisible) {
- plan.preloadPlan(this, runningTaskId, isHomeStackVisible);
+ boolean includeFrontMostExcludedTask) {
+ plan.preloadPlan(this, runningTaskId, includeFrontMostExcludedTask);
}
/** Begins loading the heavy task data according to the specified options. */
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
index acebf42..3a17d22 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java
@@ -180,7 +180,7 @@
RecentsConfiguration config = Recents.getConfiguration();
RecentsActivityLaunchState launchState = config.getLaunchState();
if (!plan.hasTasks()) {
- loader.preloadTasks(plan, -1, launchState.launchedFromHome);
+ loader.preloadTasks(plan, -1, !launchState.launchedFromHome);
}
mLaunchedFromHome = launchState.launchedFromHome;
TaskStack stack = plan.getTaskStack();
diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
index 6f7bd41..fca8d2d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java
@@ -63,7 +63,7 @@
sInstanceLoadPlan = loader.createLoadPlan(mContext);
}
if (mTriggeredFromAltTab || !sInstanceLoadPlan.hasTasks()) {
- loader.preloadTasks(sInstanceLoadPlan, runningTask.id, isHomeStackVisible);
+ loader.preloadTasks(sInstanceLoadPlan, runningTask.id, !isHomeStackVisible);
}
TaskStack stack = sInstanceLoadPlan.getTaskStack();
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 3d0de1c..1a197b6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -1391,8 +1391,9 @@
updateLayoutAlgorithm(true /* boundScroll */);
// Animate all the tasks into place
- relayoutTaskViews(new AnimationProps(DEFAULT_SYNC_STACK_DURATION,
- Interpolators.FAST_OUT_SLOW_IN));
+ relayoutTaskViews(mAwaitingFirstLayout
+ ? AnimationProps.IMMEDIATE
+ : new AnimationProps(DEFAULT_SYNC_STACK_DURATION, Interpolators.FAST_OUT_SLOW_IN));
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index dc5957d..593e170 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -2246,9 +2246,12 @@
Settings.Secure.LOCK_SCREEN_ALLOW_REMOTE_INPUT,
0,
mCurrentUserId) != 0;
+ final boolean remoteInputDpm = (dpmFlags
+ & DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT) == 0;
+
setShowLockscreenNotifications(show && allowedByDpm);
- setLockScreenAllowRemoteInput(remoteInput);
+ setLockScreenAllowRemoteInput(remoteInput && remoteInputDpm);
}
protected abstract void setAreThereNotifications();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index d2326d2..270b6ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -459,7 +459,8 @@
@Override
public String toString() {
- String result = " summary:\n " + summary.notification;
+ String result = " summary:\n "
+ + (summary != null ? summary.notification : "null");
result += "\n children size: " + children.size();
for (NotificationData.Entry child : children) {
result += "\n " + child.notification;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
index f801963..0a3197c 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/DemoModeFragment.java
@@ -154,7 +154,7 @@
getContext().sendBroadcast(intent);
intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_CLOCK);
- intent.putExtra("hhmm", "0600");
+ intent.putExtra("hhmm", "0700");
getContext().sendBroadcast(intent);
intent.putExtra(DemoMode.EXTRA_COMMAND, DemoMode.COMMAND_NETWORK);
diff --git a/services/core/java/com/android/server/PinnerService.java b/services/core/java/com/android/server/PinnerService.java
new file mode 100644
index 0000000..d48aeed
--- /dev/null
+++ b/services/core/java/com/android/server/PinnerService.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.util.EventLog;
+import android.util.Slog;
+import android.os.Binder;
+import android.os.Build;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructStat;
+
+import java.util.ArrayList;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * <p>PinnerService pins important files for key processes in memory.</p>
+ * <p>Files to pin are specified in the config_defaultPinnerServiceFiles
+ * overlay. </p>
+ */
+public final class PinnerService extends SystemService {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "PinnerService";
+
+ private final Context mContext;
+ private final ArrayList<String> mPinnedFiles = new ArrayList<String>();
+
+ private BinderService mBinderService;
+
+
+ public PinnerService(Context context) {
+ super(context);
+
+ mContext = context;
+
+ }
+
+ @Override
+ public void onStart() {
+ Slog.e(TAG, "Starting PinnerService");
+
+ mBinderService = new BinderService();
+ publishBinderService("pinner", mBinderService);
+
+ // Files to pin come from the overlay and can be specified per-device config
+ // Continue trying to pin remaining files even if there is a failure
+ String[] filesToPin = mContext.getResources().getStringArray(com.android.internal.R.array.config_defaultPinnerServiceFiles);
+ for (int i = 0; i < filesToPin.length; i++){
+ boolean success = pinFile(filesToPin[i], 0, 0);
+ if (success == true) {
+ mPinnedFiles.add(filesToPin[i]);
+ Slog.i(TAG, "Pinned file = " + filesToPin[i]);
+ } else {
+ Slog.e(TAG, "Failed to pin file = " + filesToPin[i]);
+ }
+ }
+ }
+
+ // mlock length bytes of fileToPin in memory, starting at offset
+ // length == 0 means pin from offset to end of file
+ private boolean pinFile(String fileToPin, long offset, long length) {
+ FileDescriptor fd = new FileDescriptor();
+ try {
+ fd = Os.open(fileToPin, OsConstants.O_RDONLY | OsConstants.O_CLOEXEC | OsConstants.O_NOFOLLOW, OsConstants.O_RDONLY);
+
+ StructStat sb = Os.fstat(fd);
+
+ if (offset + length > sb.st_size) {
+ Os.close(fd);
+ return false;
+ }
+
+ if (length == 0) {
+ length = sb.st_size - offset;
+ }
+
+ long address = Os.mmap(0, length, OsConstants.PROT_READ, OsConstants.MAP_PRIVATE, fd, offset);
+ Os.close(fd);
+
+ Os.mlock(address, length);
+
+ return true;
+ } catch (ErrnoException e) {
+ Slog.e(TAG, "Failed to pin file " + fileToPin + " with error " + e.getMessage());
+ if(fd.valid()) {
+ try { Os.close(fd); }
+ catch (ErrnoException eClose) {Slog.e(TAG, "Failed to close fd, error = " + eClose.getMessage());}
+ }
+ return false;
+ }
+ }
+
+
+ private final class BinderService extends Binder {
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);
+ pw.println("Pinned Files:");
+ for (int i = 0; i < mPinnedFiles.size(); i++) {
+ pw.println(mPinnedFiles.get(i));
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index 29e2e44..53c5a6d 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -868,7 +868,7 @@
return false;
}
if (this.userid == UserHandle.USER_ALL) return true;
- if (this.userid == UserHandle.USER_SYSTEM) return true;
+ if (this.isSystem) return true;
if (nid == UserHandle.USER_ALL || nid == this.userid) return true;
return supportsProfiles() && mUserProfiles.isCurrentProfile(nid);
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 8706682..defd513 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -9181,6 +9181,18 @@
void updateResizingWindows(final WindowState w) {
final WindowStateAnimator winAnimator = w.mWinAnimator;
if (w.mHasSurface && w.mLayoutSeq == mLayoutSeq && !w.isGoneForLayoutLw()) {
+ final Task task = w.getTask();
+ // In the case of stack bound animations, the window frames
+ // will update (unlike other animations which just modifiy
+ // various transformation properties). We don't want to
+ // notify the client of frame changes in this case. Not only
+ // is it a lot of churn, but the frame may not correspond
+ // to the surface size or the onscreen area at various
+ // phases in the animation, and the client will become
+ // sad and confused.
+ if (task != null && task.mStack.getBoundsAnimating()) {
+ return;
+ }
w.setInsetsChanged();
boolean configChanged = w.isConfigChanged();
if (DEBUG_CONFIGURATION && configChanged) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 9e66c28..5678ad9 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -829,8 +829,8 @@
// Adjust for surface insets.
mTmpSize.left -= scale * attrs.surfaceInsets.left;
mTmpSize.top -= scale * attrs.surfaceInsets.top;
- mTmpSize.right += scale * (attrs.surfaceInsets.left + attrs.surfaceInsets.right);
- mTmpSize.bottom += scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom);
+ mTmpSize.right += scale * attrs.surfaceInsets.right;
+ mTmpSize.bottom += scale * attrs.surfaceInsets.bottom;
}
boolean hasSurface() {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 00b83841..e306d89 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -643,6 +643,10 @@
traceBeginAndSlog("ConnectivityMetricsLoggerService");
mSystemServiceManager.startService(MetricsLoggerService.class);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
+
+ traceBeginAndSlog("PinnerService");
+ mSystemServiceManager.startService(PinnerService.class);
+ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
} catch (RuntimeException e) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting core service", e);
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 8f09bda..33e6cea 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -699,7 +699,7 @@
sDefaults.putBoolean(KEY_CARRIER_VOLTE_AVAILABLE_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_VT_AVAILABLE_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, false);
- sDefaults.putBoolean(KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, true);
+ sDefaults.putBoolean(KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL, false);
sDefaults.putInt(KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT, 2);