summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/SharedPreferences.java4
-rw-r--r--docs/html/topic/libraries/data-binding/index.jd12
-rw-r--r--docs/html/training/articles/assistant.jd306
-rw-r--r--libs/hwui/RecordingCanvas.cpp71
-rw-r--r--libs/hwui/RecordingCanvas.h2
-rw-r--r--libs/hwui/tests/unit/RecordingCanvasTests.cpp15
-rw-r--r--media/java/android/media/AudioManager.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java61
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java6
-rw-r--r--packages/WallpaperBackup/AndroidManifest.xml1
-rw-r--r--packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java2
-rw-r--r--services/core/java/com/android/server/fingerprint/FingerprintService.java14
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java4
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java16
-rw-r--r--services/tests/servicestests/assets/shortcut/shortcut_legacy_file.xml2
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java23
-rw-r--r--tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java8
20 files changed, 323 insertions, 272 deletions
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index 7f9e17641a19..4b09feda2173 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -72,7 +72,9 @@ public interface SharedPreferences {
* {@link #commit} or {@link #apply} are called.
*
* @param key The name of the preference to modify.
- * @param value The new value for the preference.
+ * @param value The new value for the preference. Passing {@code null}
+ * for this argument is equivalent to calling {@link #remove(String)} with
+ * this key.
*
* @return Returns a reference to the same Editor object, so you can
* chain put calls together.
diff --git a/docs/html/topic/libraries/data-binding/index.jd b/docs/html/topic/libraries/data-binding/index.jd
index 454bb59e7983..ddcc9f2e7ea8 100644
--- a/docs/html/topic/libraries/data-binding/index.jd
+++ b/docs/html/topic/libraries/data-binding/index.jd
@@ -601,7 +601,7 @@ any business logic inside the callback method that you invoked from the listener
<import type="com.example.User"/>
<import type="java.util.List"/>
<variable name="user" type="User"/>
- <variable name="userList" type="List<User>"/>
+ <variable name="userList" type="List<User>"/>
</data>
</pre>
<p class="caution">
@@ -945,9 +945,9 @@ android:transitionName='&commat;{"image_" + id}'
&lt;import type="android.util.SparseArray"/&gt;
&lt;import type="java.util.Map"/&gt;
&lt;import type="java.util.List"/&gt;
- &lt;variable name="list" type="List&lt;String&gt;"/&gt;
- &lt;variable name="sparse" type="SparseArray&lt;String&gt;"/&gt;
- &lt;variable name="map" type="Map&lt;String, String&gt;"/&gt;
+ &lt;variable name="list" type="List&amp;lt;String&amp;gt;"/&gt;
+ &lt;variable name="sparse" type="SparseArray&amp;lt;String&amp;gt;"/&gt;
+ &lt;variable name="map" type="Map&amp;lt;String, String&amp;gt;"/&gt;
&lt;variable name="index" type="int"/&gt;
&lt;variable name="key" type="String"/&gt;
&lt;/data&gt;
@@ -1247,7 +1247,7 @@ user.put("age", 17);
<pre>
&lt;data&gt;
&lt;import type="android.databinding.ObservableMap"/&gt;
- &lt;variable name="user" type="ObservableMap&lt;String, Object&gt;"/&gt;
+ &lt;variable name="user" type="ObservableMap&amp;lt;String, Object&amp;gt;"/&gt;
&lt;/data&gt;
&lt;TextView
@@ -1277,7 +1277,7 @@ user.add(17);
&lt;data&gt;
&lt;import type="android.databinding.ObservableList"/&gt;
&lt;import type="com.example.my.app.Fields"/&gt;
- &lt;variable name="user" type="ObservableList&lt;Object&gt;"/&gt;
+ &lt;variable name="user" type="ObservableList&amp;lt;Object&amp;gt;"/&gt;
&lt;/data&gt;
&lt;TextView
diff --git a/docs/html/training/articles/assistant.jd b/docs/html/training/articles/assistant.jd
index a1fbd6ba1634..703b3778a275 100644
--- a/docs/html/training/articles/assistant.jd
+++ b/docs/html/training/articles/assistant.jd
@@ -11,110 +11,92 @@ page.article=true
<div id="tb">
<h2>In this document</h2>
<ol>
- <li><a href="#assist_api">Using the Assist API</a>
+ <li><a href="#assist_api">Using the Assistant</a>
<ol>
- <li><a href="#assist_api_lifecycle">Assist API Lifecycle</a></li>
- <li><a href="#source_app">Source App</a></li>
- <li><a href="#destination_app">Destination App</a></li>
+ <li><a href="#source_app">Source app</a></li>
+ <li><a href="#destination_app">Destination app</a></li>
</ol>
</li>
- <li><a href="#implementing_your_own_assistant">Implementing your
- own assistant</a></li>
+ <li><a href="#implementing_your_own_assistant">Implementing Your
+ Own Assistant</a></li>
</ol>
</div>
</div>
<p>
Android 6.0 Marshmallow introduces a new way for users to engage with apps
- through the assistant.
-</p>
+ through the assistant. The assistant is a top-level window that users can view to obtain
+ contextually relevant actions for the current activity. These actions might include deep links
+ to other apps on the device.</p>
<p>
- Users summon the assistant with a long-press on the Home button or by saying
- the {@link android.service.voice.AlwaysOnHotwordDetector keyphrase}. In
- response to the long-press, the system opens a top-level window that displays
- contextually relevant actions for the current activity. These potential
- actions might include deep links to other apps on the device.
+ Users activate the assistant with a long press on the Home button or by saying a
+ <a href="{@docRoot}reference/android/service/voice/AlwaysOnHotwordDetector.html">keyphrase</a>.
+ In response, the system opens a top-level window that displays contextually
+ relevant actions.
</p>
<p>
- This guide explains how Android apps use Android's Assist API to improve the
- assistant user experience.
+ Google App implements the assistant overlay window through a feature called
+ Now on Tap, which works with the Android platform-level functionality. The system allows
+ the user to select an assistant app, which obtains contextual information from your app
+ using Android’s Assist API.
</p>
-
-
-<h2 id="assist_api">Using the Assist API</h2>
-
<p>
- The example below shows how Google Now integrates with the Android assistant
- using a feature called Now on Tap.
+ This guide explains how Android apps use Android's Assist API to improve the assistant
+ user experience.
+<p/>
</p>
+
+<h2 id="assist_api">Using the Assistant</h2>
+
<p>
- The assistant overlay window in our example (2, 3) is implemented by Google
- Now through a feature called Now on Tap, which works in concert with the
- Android platform-level functionality. The system allows the user to select
- the assistant app (Figure 2) that obtains contextual information from the
- <em>source</em> app using the Assist API which is a part of the platform.
+ Figure 1 illustrates a typical user interaction with the assistant. When the user long-presses
+ the Home button, the Assist API callbacks are invoked
+ in the <em>source</em> app (step 1). The assistant renders the overlay window (steps 2 and 3),
+ and then the user selects the action to perform. The assistant executes the selected action,
+ such as firing an intent with a deep link to the (<em>destination</em>) restaurant app (step 4).
</p>
-
<div>
<img src="{@docRoot}images/training/assistant/image01.png">
<p class="img-caption" style="text-align:center;">
Figure 1. Assistant interaction example with the Now on Tap feature of
- Google Now
+ the Google App
</p>
</div>
<p>
- An Android user first configures the assistant and can change system options
- such as using text and view hierarchy as well as the screenshot of the
- current screen (Figure 2).
-</p>
-
-<p>
- From there, the assistant receives the information only when the user
- activates assistance, such as when they tap and hold the Home button ( shown
- in Figure 1, step 1).
+ Users can configure the assistant by selecting <strong>Settings > Apps > Default Apps >
+ Assist &amp; voice input</strong>. Users can change system options such as accessing
+ the screen contents as text and accessing a screenshot, as shown in Figure 2.
</p>
-<div style="float:right;margin:1em;max-width:300px">
+<div id="assist-input-settings" style="float:right;margin:1em;max-width:300px">
<img src="{@docRoot}images/training/assistant/image02.png">
<p class="img-caption" style="text-align:center;">
- Figure 2. Assist &amp; voice input settings (<em>Settings/Apps/Default
- Apps/Assist &amp; voice input</em>)
+ Figure 2. Assist &amp; voice input settings
</p>
</div>
-<h3 id="assist_api_lifecycle">Assist API Lifecycle</h3>
-
-<p>
- Going back to our example from Figure 1, the Assist API callbacks are invoked
- in the <em>source</em> app after step 1 (user long-presses the Home button)
- and before step 2 (the assistant renders the overlay window). Once the user
- selects the action to perform (step 3), the assistant executes it, for
- example by firing an intent with a deep link to the (<em>destination</em>)
- restaurant app (step 4).
-</p>
-
-<h3 id="source_app">Source App</h3>
+<h3 id="source_app">Source app</h3>
<p>
- In most cases, your app does not need to do anything extra to integrate with
- the assistant if you already follow <a href=
+ To ensure that your app works with the assistant as a source of information for the user,
+ you need only follow <a href=
"{@docRoot}guide/topics/ui/accessibility/apps.html">accessibility best
practices</a>. This section describes how to provide additional information
- to help improve the assistant user experience, as well as scenarios, such as
- custom Views, that need special handling.
+ to help improve the assistant user experience as well as scenarios
+ that need special handling, such as custom Views.
</p>
-
-<h4 id="share_additional_information_with_the_assistant">Share Additional Information with the Assistant</h4>
+<h4 id="share_additional_information_with_the_assistant">Share additional information
+ with the assistant</h4>
<p>
In addition to the text and the screenshot, your app can share
- <em>additional</em> information with the assistant. For example, your music
- app can choose to pass current album information, so that the assistant can
+ other information with the assistant. For example, your music
+ app can choose to pass current album information so that the assistant can
suggest smarter actions tailored to the current activity.
</p>
@@ -122,13 +104,13 @@ page.article=true
To provide additional information to the assistant, your app provides
<em>global application context</em> by registering an app listener and
supplies activity-specific information with activity callbacks as shown in
- Figure 3.
+ Figure 3:
</p>
<div>
<img src="{@docRoot}images/training/assistant/image03.png">
<p class="img-caption" style="text-align:center;">
- Figure 3. Assist API lifecycle sequence diagram.
+ Figure 3. Assist API lifecycle sequence diagram
</p>
</div>
@@ -136,43 +118,42 @@ page.article=true
To provide global application context, the app creates an implementation of
{@link android.app.Application.OnProvideAssistDataListener} and registers it
using {@link
- android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener)}.
- In order to provide activity-specific contextual information, activity
- overrides {@link android.app.Activity#onProvideAssistData(android.os.Bundle)}
+ android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener) registerOnProvideAssistDataListener()}.
+ To provide activity-specific contextual information, the activity
+ overrides {@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()}
and {@link
- android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent)}.
+ android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()}.
The two activity methods are called <em>after</em> the optional global
- callback (registered with {@link
- android.app.Application#registerOnProvideAssistDataListener(android.app.Application.OnProvideAssistDataListener)})
- is invoked. Since the callbacks execute on the main thread, they should
+ callback is invoked. Because the callbacks execute on the main thread, they should
complete <a href="{@docRoot}training/articles/perf-anr.html">promptly</a>.
The callbacks are invoked only when the activity is <a href=
"{@docRoot}reference/android/app/Activity.html#ActivityLifecycle">running</a>.
</p>
-<h5 id="providing_context">Providing Context</h5>
+<h5 id="providing_context">Providing context</h5>
<p>
- {@link android.app.Activity#onProvideAssistData(android.os.Bundle)} is called
- when the user is requesting the assistant to build a full {@link
+ When the user activates the assistant,
+ {@link android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()} is called to build a full
+ {@link
android.content.Intent#ACTION_ASSIST} Intent with all of the context of the
current application represented as an instance of the {@link
android.app.assist.AssistStructure}. You can override this method to place
- into the bundle anything you would like to appear in the
- <code>EXTRA_ASSIST_CONTEXT</code> part of the assist Intent.
+ anything you like into the bundle to appear in the
+ {@link android.content.Intent#EXTRA_ASSIST_CONTEXT} part of the assist intent.
</p>
-<h5 id="describing_content">Describing Content</h5>
+<h5 id="describing_content">Describing content</h5>
<p>
Your app can implement {@link
- android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent)}
- to improve assistant user experience by providing references to content
+ android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()}
+ to improve the assistant user experience by providing content-related references
related to the current activity. You can describe the app content using the
- common vocabulary defined by <a href="https://schema.org">Schema.org</a>
+ common vocabulary defined by <a href="https://schema.org" class="external-link">Schema.org</a>
through a JSON-LD object. In the example below, a music app provides
- structured data to describe the music album the user is currently
- looking at.
+ structured data to describe the music album that the user is currently
+ viewing:
</p>
<pre class="prettyprint">
@@ -191,127 +172,158 @@ public void onProvideAssistContent(AssistContent <strong>assistContent</strong>)
</pre>
<p>
- Custom implementations of {@link
- android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent)}
- may also adjust the provided {@link
- android.app.assist.AssistContent#setIntent(android.content.Intent) content
- intent} to better reflect the top-level context of the activity, supply
- {@link android.app.assist.AssistContent#setWebUri(android.net.Uri) the URI}
- of the displayed content, and fill in its {@link
- android.app.assist.AssistContent#setClipData(android.content.ClipData)} with
- additional content of interest that the user is currently viewing.
+ You can also improve the user experience with custom implementations of
+ {@link
+ android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()},
+ which can provide the following benefits:
+</p>
+<ul>
+ <li><a href="{@docRoot}reference/android/app/assist/AssistContent.html#setIntent(android.content.Intent)">
+ Adjusts the provided content
+ intent</a> to
+ better reflect the top-level context of the activity.</li>
+ <li><a href="{@docRoot}reference/android/app/assist/AssistContent.html#setWebUri(android.net.Uri)">
+ Supplies the URI</a>
+ of the displayed content.</li>
+ <li>Fills in {@link
+ android.app.assist.AssistContent#setClipData(android.content.ClipData) setClipData()} with additional
+ content of interest that the user is currently viewing.</li>
+</ul>
+<p class="note">
+ <strong>Note: </strong>Apps that use a custom text selection implementation likely need
+ to implement {@link
+ android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()}
+ and call {@link android.app.assist.AssistContent#setClipData(android.content.ClipData) setClipData()}.
</p>
-<h4 id="default_implementation">Default Implementation</h4>
+<h4 id="default_implementation">Default implementation</h4>
<p>
- If neither {@link
- android.app.Activity#onProvideAssistData(android.os.Bundle)} nor {@link
- android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent)}
- callbacks are implemented, the system will still proceed and pass the
- information collected automatically to the assistant unless the current
+ If neither the {@link
+ android.app.Activity#onProvideAssistData(android.os.Bundle) onProvideAssistData()} nor the {@link
+ android.app.Activity#onProvideAssistContent(android.app.assist.AssistContent) onProvideAssistContent()}
+ callback is implemented, the system still proceeds and passes the
+ automatically collected information to the assistant unless the current
window is flagged as <a href="#excluding_views">secure</a>.
As shown in Figure 3, the system uses the default implementations of {@link
- android.view.View#onProvideStructure(android.view.ViewStructure)} and {@link
- android.view.View#onProvideVirtualStructure(android.view.ViewStructure)} to
+ android.view.View#onProvideStructure(android.view.ViewStructure) onProvideStructure()} and {@link
+ android.view.View#onProvideVirtualStructure(android.view.ViewStructure) onProvideVirtualStructure()} to
collect text and view hierarchy information. If your view implements custom
- text drawing, you should override {@link
- android.view.View#onProvideStructure(android.view.ViewStructure)} to provide
+ text drawing, override {@link
+ android.view.View#onProvideStructure(android.view.ViewStructure) onProvideStructure()} to provide
the assistant with the text shown to the user by calling {@link
- android.view.ViewStructure#setText(java.lang.CharSequence)}.
+ android.view.ViewStructure#setText(java.lang.CharSequence) setText(CharSequence)}.
</p>
<p>
- <strong>In most cases, implementing accessibility support will enable the
- assistant to obtain the information it needs.</strong> This includes
- providing {@link android.R.attr#contentDescription
- android:contentDescription} attributes, populating {@link
- android.view.accessibility.AccessibilityNodeInfo} for custom views, making
- sure custom {@link android.view.ViewGroup ViewGroups} correctly {@link
- android.view.ViewGroup#getChildAt(int) expose} their children, and following
- the best practices described in <a href=
- "{@docRoot}guide/topics/ui/accessibility/apps.html">“Making Applications
- Accessible”</a>.
-</p>
+ <em>In most cases, implementing accessibility support enables the
+ assistant to obtain the information it needs.</em> To implement accessibility support,
+ observe the best practices described in <a href=
+ "{@docRoot}guide/topics/ui/accessibility/apps.html">Making Applications
+ Accessible</a>, including the following:</p>
+
+<ul>
+ <li>Provide {@link android.R.attr#contentDescription
+ android:contentDescription} attributes.</li>
+ <li>Populate {@link
+ android.view.accessibility.AccessibilityNodeInfo} for custom views.</li>
+ <li>Make
+ sure that custom {@link android.view.ViewGroup ViewGroup} objects correctly
+ <a href="{@docRoot}reference/android/view/ViewGroup.html#getChildAt(int)">expose</a>
+ their children.</li>
+</ul>
<h4 id="excluding_views">Excluding views from the assistant</h4>
<p>
- An activity can exclude the current view from the assistant. This is accomplished
+ To handle sensitive information, your app can exclude the current view from the assistant
by setting the {@link android.view.WindowManager.LayoutParams#FLAG_SECURE
- FLAG_SECURE} layout parameter of the WindowManager and must be done
- explicitly for every window created by the activity, including Dialogs. Your
- app can also use {@link android.view.SurfaceView#setSecure(boolean)
- SurfaceView.setSecure} to exclude a surface from the assistant. There is no
+ FLAG_SECURE} layout parameter of the {@link android.view.WindowManager}. You must set {@link
+ android.view.WindowManager.LayoutParams#FLAG_SECURE
+ FLAG_SECURE} explicitly for
+ every window created by the activity, including dialogs. Your app can also use
+ {@link android.view.SurfaceView#setSecure(boolean) setSecure()} to exclude
+ a surface from the assistant. There is no
global (app-level) mechanism to exclude all views from the assistant. Note
- that <code>FLAG_SECURE</code> does not cause the Assist API callbacks to stop
- firing. The activity which uses <code>FLAG_SECURE</code> can still explicitly
+ that {@link android.view.WindowManager.LayoutParams#FLAG_SECURE
+ FLAG_SECURE} does not cause the Assist API callbacks to stop
+ firing. The activity that uses {@link android.view.WindowManager.LayoutParams#FLAG_SECURE
+ FLAG_SECURE} can still explicitly
provide information to the assistant using the callbacks described earlier
this guide.
</p>
-<h4 id="voice_interactions">Voice Interactions</h4>
+<p class="note"><strong>Note: </strong>For enterprise accounts (Android for Work),
+ the administrator can disable
+ the collection of assistant data for the work profile by using the {@link
+ android.app.admin.DevicePolicyManager#setScreenCaptureDisabled(android.content.ComponentName, boolean)
+ setScreenCaptureDisabled()} method of the {@link android.app.admin.DevicePolicyManager} API.</p>
+
+<h4 id="voice_interactions">Voice interactions</h4>
<p>
- Assist API callbacks are also invoked upon {@link
- android.service.voice.AlwaysOnHotwordDetector keyphrase detection}. For more
- information see the <a href="https://developers.google.com/voice-actions/">voice
- actions</a> documentation.
+ Assist API callbacks are also invoked upon
+ <a href="{@docRoot}reference/android/service/voice/AlwaysOnHotwordDetector.html">keyphrase
+ detection</a>. For more information, see the
+ <a href="https://developers.google.com/voice-actions/" class="external-link">Voice
+ Actions</a> documentation.
</p>
<h4 id="z-order_considerations">Z-order considerations</h4>
<p>
The assistant uses a lightweight overlay window displayed on top of the
- current activity. The assistant can be summoned by the user at any time.
- Therefore, apps should not create permanent {@link
- android.Manifest.permission#SYSTEM_ALERT_WINDOW system alert}
- windows interfering with the overlay window shown in Figure 4.
+ current activity. Because the user can activate the assistant at any time,
+ don't create permanent <a
+ href="{@docRoot}reference/android/Manifest.permission.html#SYSTEM_ALERT_WINDOW">
+ system alert</a> windows that interfere with the overlay window, as shown in
+ Figure 4.
</p>
<div style="">
<img src="{@docRoot}images/training/assistant/image04.png">
<p class="img-caption" style="text-align:center;">
- Figure 4. Assist layer Z-order.
+ Figure 4. Assist layer Z-order
</p>
</div>
<p>
- If your app uses {@link
- android.Manifest.permission#SYSTEM_ALERT_WINDOW system alert} windows, it
- must promptly remove them as leaving them on the screen will degrade user
- experience and annoy the users.
+ If your app uses <a
+ href="{@docRoot}reference/android/Manifest.permission.html#SYSTEM_ALERT_WINDOW">
+ system alert</a> windows, remove them promptly because leaving them on the
+ screen degrades the user experience.
</p>
-<h3 id="destination_app">Destination App</h3>
+<h3 id="destination_app">Destination app</h3>
<p>
- The matching between the current user context and potential actions displayed
- in the overlay window (shown in step 3 in Figure 1) is specific to the
- assistant’s implementation. However, consider adding <a href=
- "{@docRoot}training/app-indexing/deep-linking.html">deep linking</a> support
- to your app. The assistant will typically take advantage of deep linking. For
- example, Google Now uses deep linking and <a href=
- "https://developers.google.com/app-indexing/">App Indexing</a> in order to
+ The assistant typically takes advantage of deep linking to find destination apps. To make your
+ app a potential destination app, consider adding <a href=
+ "{@docRoot}training/app-indexing/deep-linking.html">deep linking</a> support. The matching
+ between the current user context and deep links or other potential actions displayed in the
+ overlay window (shown in step 3 in Figure 1) is specific to the assistant’s implementation.
+ For
+ example, the Google App uses deep linking and <a href=
+ "https://developers.google.com/app-indexing/" class="external-link">Firebase App Indexing</a> in order to
drive traffic to destination apps.
</p>
-<h2 id="implementing_your_own_assistant">Implementing your own assistant </h2>
+<h2 id="implementing_your_own_assistant">Implementing Your Own Assistant </h2>
<p>
- Some developers may wish to implement their own assistant. As shown in Figure
- 2, the active assistant app can be selected by the Android user. The
+ You may wish to implement your own assistant. As shown in <a href="#assist-input-settings">Figure
+ 2</a>, the user can select the active assistant app. The
assistant app must provide an implementation of {@link
android.service.voice.VoiceInteractionSessionService} and {@link
android.service.voice.VoiceInteractionSession} as shown in <a href=
- "https://android.googlesource.com/platform/frameworks/base/+/android-5.0.1_r1/tests/VoiceInteraction?autodive=0%2F%2F%2F%2F%2F%2F">
- this</a> example and it requires the {@link
- android.Manifest.permission#BIND_VOICE_INTERACTION} permission. It can then
+ "https://android.googlesource.com/platform/frameworks/base/+/marshmallow-release/tests/VoiceInteraction/" class="external-link">
+ this <code>VoiceInteraction</code> example</a>. It also requires the {@link
+ android.Manifest.permission#BIND_VOICE_INTERACTION} permission. The assistant can then
receive the text and view hierarchy represented as an instance of the {@link
android.app.assist.AssistStructure} in {@link
android.service.voice.VoiceInteractionSession#onHandleAssist(android.os.Bundle,
android.app.assist.AssistStructure,android.app.assist.AssistContent) onHandleAssist()}.
- The assistant receives the screenshot through {@link
+ It receives the screenshot through {@link
android.service.voice.VoiceInteractionSession#onHandleScreenshot(android.graphics.Bitmap)
onHandleScreenshot()}.
</p>
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index 9a242fb51569..27e6a12fb59e 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -149,50 +149,53 @@ int RecordingCanvas::saveLayer(float left, float top, float right, float bottom,
// Map visible bounds back to layer space, and intersect with parameter bounds
Rect layerBounds = visibleBounds;
- Matrix4 inverse;
- inverse.loadInverse(*previous.transform);
- inverse.mapRect(layerBounds);
- layerBounds.doIntersect(unmappedBounds);
+ if (CC_LIKELY(!layerBounds.isEmpty())) {
+ // if non-empty, can safely map by the inverse transform
+ Matrix4 inverse;
+ inverse.loadInverse(*previous.transform);
+ inverse.mapRect(layerBounds);
+ layerBounds.doIntersect(unmappedBounds);
+ }
int saveValue = mState.save((int) flags);
Snapshot& snapshot = *mState.writableSnapshot();
// layerBounds is in original bounds space, but clipped by current recording clip
- if (layerBounds.isEmpty() || unmappedBounds.isEmpty()) {
- // Don't bother recording layer, since it's been rejected
+ if (!layerBounds.isEmpty() && !unmappedBounds.isEmpty()) {
if (CC_LIKELY(clippedLayer)) {
- snapshot.resetClip(0, 0, 0, 0);
+ auto previousClip = getRecordedClip(); // capture before new snapshot clip has changed
+ if (addOp(alloc().create_trivial<BeginLayerOp>(
+ unmappedBounds,
+ *previous.transform, // transform to *draw* with
+ previousClip, // clip to *draw* with
+ refPaint(paint))) >= 0) {
+ snapshot.flags |= Snapshot::kFlagIsLayer | Snapshot::kFlagIsFboLayer;
+ snapshot.initializeViewport(unmappedBounds.getWidth(), unmappedBounds.getHeight());
+ snapshot.transform->loadTranslate(-unmappedBounds.left, -unmappedBounds.top, 0.0f);
+
+ Rect clip = layerBounds;
+ clip.translate(-unmappedBounds.left, -unmappedBounds.top);
+ snapshot.resetClip(clip.left, clip.top, clip.right, clip.bottom);
+ snapshot.roundRectClipState = nullptr;
+ return saveValue;
+ }
+ } else {
+ if (addOp(alloc().create_trivial<BeginUnclippedLayerOp>(
+ unmappedBounds,
+ *mState.currentSnapshot()->transform,
+ getRecordedClip(),
+ refPaint(paint))) >= 0) {
+ snapshot.flags |= Snapshot::kFlagIsLayer;
+ return saveValue;
+ }
}
- return saveValue;
}
+ // Layer not needed, so skip recording it...
if (CC_LIKELY(clippedLayer)) {
- auto previousClip = getRecordedClip(); // note: done before new snapshot's clip has changed
-
- snapshot.flags |= Snapshot::kFlagIsLayer | Snapshot::kFlagIsFboLayer;
- snapshot.initializeViewport(unmappedBounds.getWidth(), unmappedBounds.getHeight());
- snapshot.transform->loadTranslate(-unmappedBounds.left, -unmappedBounds.top, 0.0f);
-
- Rect clip = layerBounds;
- clip.translate(-unmappedBounds.left, -unmappedBounds.top);
- snapshot.resetClip(clip.left, clip.top, clip.right, clip.bottom);
- snapshot.roundRectClipState = nullptr;
-
- addOp(alloc().create_trivial<BeginLayerOp>(
- unmappedBounds,
- *previous.transform, // transform to *draw* with
- previousClip, // clip to *draw* with
- refPaint(paint)));
- } else {
- snapshot.flags |= Snapshot::kFlagIsLayer;
-
- addOp(alloc().create_trivial<BeginUnclippedLayerOp>(
- unmappedBounds,
- *mState.currentSnapshot()->transform,
- getRecordedClip(),
- refPaint(paint)));
+ // ... and set empty clip to reject inner content, if possible
+ snapshot.resetClip(0, 0, 0, 0);
}
-
return saveValue;
}
@@ -625,7 +628,7 @@ void RecordingCanvas::callDrawGLFunction(Functor* functor,
functor));
}
-size_t RecordingCanvas::addOp(RecordedOp* op) {
+int RecordingCanvas::addOp(RecordedOp* op) {
// skip op with empty clip
if (op->localClip && op->localClip->rect.isEmpty()) {
// NOTE: this rejection happens after op construction/content ref-ing, so content ref'd
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 11773d4c1032..efa6b915ac7a 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -208,7 +208,7 @@ private:
void drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint);
- size_t addOp(RecordedOp* op);
+ int addOp(RecordedOp* op);
// ----------------------------------------------------------------------------
// lazy object copy
// ----------------------------------------------------------------------------
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 51797b4d632a..fdf0b547fb54 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -545,6 +545,21 @@ TEST(RecordingCanvas, saveLayer_rotateClipped) {
EXPECT_EQ(3, count);
}
+TEST(RecordingCanvas, saveLayer_rejectBegin) {
+ auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
+ canvas.save(SaveFlags::MatrixClip);
+ canvas.translate(0, -20); // avoid identity case
+ // empty clip rect should force layer + contents to be rejected
+ canvas.clipRect(0, -20, 200, -20, SkRegion::kIntersect_Op);
+ canvas.saveLayerAlpha(0, 0, 200, 200, 128, SaveFlags::ClipToLayer);
+ canvas.drawRect(0, 0, 200, 200, SkPaint());
+ canvas.restore();
+ canvas.restore();
+ });
+
+ ASSERT_EQ(0u, dl->getOps().size()) << "Begin/Rect/End should all be rejected.";
+}
+
TEST(RecordingCanvas, drawRenderNode_rejection) {
auto child = TestUtils::createNode(50, 50, 150, 150,
[](RenderProperties& props, Canvas& canvas) {
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index f19a2624457e..33c1c3f6acc0 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -3289,7 +3289,10 @@ public class AudioManager {
/**
* Used as a key for {@link #getProperty} to request the native or optimal output sample rate
- * for this device's primary output stream, in decimal Hz.
+ * for this device's low latency output stream, in decimal Hz. Latency-sensitive apps
+ * should use this value as a default, and offer the user the option to override it.
+ * The low latency output stream is typically either the device's primary output stream,
+ * or another output stream with smaller buffers.
*/
// FIXME Deprecate
public static final String PROPERTY_OUTPUT_SAMPLE_RATE =
@@ -3297,7 +3300,10 @@ public class AudioManager {
/**
* Used as a key for {@link #getProperty} to request the native or optimal output buffer size
- * for this device's primary output stream, in decimal PCM frames.
+ * for this device's low latency output stream, in decimal PCM frames. Latency-sensitive apps
+ * should use this value as a minimum, and offer the user the option to override it.
+ * The low latency output stream is typically either the device's primary output stream,
+ * or another output stream with smaller buffers.
*/
// FIXME Deprecate
public static final String PROPERTY_OUTPUT_FRAMES_PER_BUFFER =
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
index b5753ba39a43..745f5a5a773e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java
@@ -275,10 +275,16 @@ public class TaskStack {
new RectF(0, 0.5f, 1, 1));
@Override
- public boolean acceptsDrop(int x, int y, int width, int height, boolean isCurrentTarget) {
- return isCurrentTarget
- ? areaContainsPoint(expandedTouchDockArea, width, height, x, y)
- : areaContainsPoint(touchArea, width, height, x, y);
+ public boolean acceptsDrop(int x, int y, int width, int height, Rect insets,
+ boolean isCurrentTarget) {
+ if (isCurrentTarget) {
+ getMappedRect(expandedTouchDockArea, width, height, mTmpRect);
+ return mTmpRect.contains(x, y);
+ } else {
+ getMappedRect(touchArea, width, height, mTmpRect);
+ updateBoundsWithSystemInsets(mTmpRect, insets);
+ return mTmpRect.contains(x, y);
+ }
}
// Represents the view state of this dock state
@@ -423,6 +429,7 @@ public class TaskStack {
private final RectF touchArea;
private final RectF dockArea;
private final RectF expandedTouchDockArea;
+ private static final Rect mTmpRect = new Rect();
/**
* @param createMode used to pass to ActivityManager to dock the task
@@ -452,23 +459,11 @@ public class TaskStack {
}
/**
- * Returns whether {@param x} and {@param y} are contained in the area scaled to the
- * given {@param width} and {@param height}.
- */
- public boolean areaContainsPoint(RectF area, int width, int height, float x, float y) {
- int left = (int) (area.left * width);
- int top = (int) (area.top * height);
- int right = (int) (area.right * width);
- int bottom = (int) (area.bottom * height);
- return x >= left && y >= top && x <= right && y <= bottom;
- }
-
- /**
* Returns the docked task bounds with the given {@param width} and {@param height}.
*/
- public Rect getPreDockedBounds(int width, int height) {
- return new Rect((int) (dockArea.left * width), (int) (dockArea.top * height),
- (int) (dockArea.right * width), (int) (dockArea.bottom * height));
+ public Rect getPreDockedBounds(int width, int height, Rect insets) {
+ getMappedRect(dockArea, width, height, mTmpRect);
+ return updateBoundsWithSystemInsets(mTmpRect, insets);
}
/**
@@ -511,10 +506,34 @@ public class TaskStack {
int top = dockArea.bottom < 1f
? 0
: insets.top;
- layoutAlgorithm.getTaskStackBounds(displayRect, windowRectOut, top, insets.left,
- insets.right, taskStackBounds);
+ // For now, ignore the left insets since we always dock on the left and show Recents
+ // on the right
+ layoutAlgorithm.getTaskStackBounds(displayRect, windowRectOut, top, 0, insets.right,
+ taskStackBounds);
return taskStackBounds;
}
+
+ /**
+ * Returns the expanded bounds in certain dock sides such that the bounds account for the
+ * system insets (namely the vertical nav bar). This call modifies and returns the given
+ * {@param bounds}.
+ */
+ private Rect updateBoundsWithSystemInsets(Rect bounds, Rect insets) {
+ if (dockSide == DOCKED_LEFT) {
+ bounds.right += insets.left;
+ } else if (dockSide == DOCKED_RIGHT) {
+ bounds.left -= insets.right;
+ }
+ return bounds;
+ }
+
+ /**
+ * Returns the mapped rect to the given dimensions.
+ */
+ private void getMappedRect(RectF bounds, int width, int height, Rect out) {
+ out.set((int) (bounds.left * width), (int) (bounds.top * height),
+ (int) (bounds.right * width), (int) (bounds.bottom * height));
+ }
}
// A comparator that sorts tasks by their freeform state
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java b/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java
index 3ad368cbf60a..f2a631078d3c 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/DropTarget.java
@@ -16,6 +16,8 @@
package com.android.systemui.recents.views;
+import android.graphics.Rect;
+
/**
* Represents a drop target for a drag gesture.
*/
@@ -25,5 +27,5 @@ public interface DropTarget {
* Returns whether this target can accept this drop. The x,y are relative to the top level
* RecentsView, and the width/height are of the RecentsView.
*/
- boolean acceptsDrop(int x, int y, int width, int height, boolean isCurrentTarget);
+ boolean acceptsDrop(int x, int y, int width, int height, Rect insets, boolean isCurrentTarget);
}
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 41622083c792..24ef433bd4d8 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -104,7 +104,7 @@ public class RecentsView extends FrameLayout {
private boolean mLastTaskLaunchedWasFreeform;
@ViewDebug.ExportedProperty(category="recents")
- private Rect mSystemInsets = new Rect();
+ Rect mSystemInsets = new Rect();
private int mDividerSize;
private Drawable mBackgroundScrim = new ColorDrawable(
@@ -223,13 +223,6 @@ public class RecentsView extends FrameLayout {
}
/**
- * Returns whether the nav bar is on the right.
- */
- public boolean isNavBarOnRight() {
- return mSystemInsets.right > 0;
- }
-
- /**
* Returns whether the last task launched was in the freeform stack or not.
*/
public boolean isLastTaskLaunchedFreeform() {
@@ -746,9 +739,10 @@ public class RecentsView extends FrameLayout {
? overrideHintAlpha
: viewState.hintTextAlpha;
Rect bounds = isDefaultDockState
- ? dockState.getPreDockedBounds(getMeasuredWidth(), getMeasuredHeight())
+ ? dockState.getPreDockedBounds(getMeasuredWidth(), getMeasuredHeight(),
+ mSystemInsets)
: dockState.getDockedBounds(getMeasuredWidth(), getMeasuredHeight(),
- mDividerSize, mSystemInsets, getResources());
+ mDividerSize, mSystemInsets, getResources());
if (viewState.dockAreaOverlay.getCallback() != this) {
viewState.dockAreaOverlay.setCallback(this);
viewState.dockAreaOverlay.setBounds(bounds);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
index 9ff7a68208c9..265f3197d8da 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java
@@ -47,14 +47,10 @@ import java.util.ArrayList;
* Represents the dock regions for each orientation.
*/
class DockRegion {
- // The phone landscape dock states correspond to the opposite end of the screen that the nav bar
- // appears
- public static TaskStack.DockState[] PHONE_LANDSCAPE_LEFT = {
+ public static TaskStack.DockState[] PHONE_LANDSCAPE = {
+ // We only allow docking to the left in landscape for now on small devices
TaskStack.DockState.LEFT
};
- public static TaskStack.DockState[] PHONE_LANDSCAPE_RIGHT = {
- TaskStack.DockState.RIGHT
- };
public static TaskStack.DockState[] PHONE_PORTRAIT = {
// We only allow docking to the top for now on small devices
TaskStack.DockState.TOP
@@ -123,13 +119,7 @@ public class RecentsViewTouchHandler {
if (config.isLargeScreen) {
return isLandscape ? DockRegion.TABLET_LANDSCAPE : DockRegion.TABLET_PORTRAIT;
} else {
- if (isLandscape) {
- return mRv.isNavBarOnRight()
- ? DockRegion.PHONE_LANDSCAPE_LEFT
- : DockRegion.PHONE_LANDSCAPE_RIGHT;
- } else {
- return DockRegion.PHONE_PORTRAIT;
- }
+ return isLandscape ? DockRegion.PHONE_LANDSCAPE : DockRegion.PHONE_PORTRAIT;
}
}
@@ -244,7 +234,7 @@ public class RecentsViewTouchHandler {
// Give priority to the current drop target to retain the touch handling
if (mLastDropTarget != null) {
if (mLastDropTarget.acceptsDrop((int) evX, (int) evY, width, height,
- true /* isCurrentTarget */)) {
+ mRv.mSystemInsets, true /* isCurrentTarget */)) {
currentDropTarget = mLastDropTarget;
}
}
@@ -253,7 +243,7 @@ public class RecentsViewTouchHandler {
if (currentDropTarget == null) {
for (DropTarget target : mDropTargets) {
if (target.acceptsDrop((int) evX, (int) evY, width, height,
- false /* isCurrentTarget */)) {
+ mRv.mSystemInsets, false /* isCurrentTarget */)) {
currentDropTarget = target;
break;
}
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 fef05562b98b..d29fbfd3daa1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -218,7 +218,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
// The drop targets for a task drag
private DropTarget mFreeformWorkspaceDropTarget = new DropTarget() {
@Override
- public boolean acceptsDrop(int x, int y, int width, int height, boolean isCurrentTarget) {
+ public boolean acceptsDrop(int x, int y, int width, int height, Rect insets,
+ boolean isCurrentTarget) {
// This drop target has a fixed bounds and should be checked last, so just fall through
// if it is the current target
if (!isCurrentTarget) {
@@ -230,7 +231,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
private DropTarget mStackDropTarget = new DropTarget() {
@Override
- public boolean acceptsDrop(int x, int y, int width, int height, boolean isCurrentTarget) {
+ public boolean acceptsDrop(int x, int y, int width, int height, Rect insets,
+ boolean isCurrentTarget) {
// This drop target has a fixed bounds and should be checked last, so just fall through
// if it is the current target
if (!isCurrentTarget) {
diff --git a/packages/WallpaperBackup/AndroidManifest.xml b/packages/WallpaperBackup/AndroidManifest.xml
index b8cea20afcd4..c548101080b4 100644
--- a/packages/WallpaperBackup/AndroidManifest.xml
+++ b/packages/WallpaperBackup/AndroidManifest.xml
@@ -24,6 +24,7 @@
android:process="system"
android:killAfterRestore="false"
android:allowBackup="true"
+ android:backupInForeground="true"
android:backupAgent=".WallpaperBackupAgent"
android:fullBackupOnly="true" >
</application>
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index 402d9adf0e7c..82b305087707 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -238,7 +238,7 @@ public class WallpaperBackupAgent extends BackupAgent {
Slog.v(TAG, "Restored crop hint " + cropHint);
}
try (FileInputStream in = new FileInputStream(stage)) {
- mWm.setStream(in, cropHint, true, which);
+ mWm.setStream(in, cropHint.isEmpty() ? null : cropHint, true, which);
} finally {} // auto-closes 'in'
}
}
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 1066434f10f1..df7fcb59b8c0 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -470,10 +470,10 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
/**
* @param opPackageName name of package for caller
- * @param foregroundOnly only allow this call while app is in the foreground
+ * @param requireForeground only allow this call while app is in the foreground
* @return true if caller can use fingerprint API
*/
- private boolean canUseFingerprint(String opPackageName, boolean foregroundOnly, int uid,
+ private boolean canUseFingerprint(String opPackageName, boolean requireForeground, int uid,
int pid) {
checkPermission(USE_FINGERPRINT);
if (isKeyguard(opPackageName)) {
@@ -488,7 +488,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
Slog.w(TAG, "Rejecting " + opPackageName + " ; permission denied");
return false;
}
- if (foregroundOnly && !isForegroundActivity(uid, pid)) {
+ if (requireForeground && !(isForegroundActivity(uid, pid) || currentClient(opPackageName))){
Slog.w(TAG, "Rejecting " + opPackageName + " ; not in foreground");
return false;
}
@@ -496,6 +496,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
}
/**
+ * @param opPackageName package of the caller
+ * @return true if this is the same client currently using fingerprint
+ */
+ private boolean currentClient(String opPackageName) {
+ return mCurrentClient != null && mCurrentClient.getOwnerString().equals(opPackageName);
+ }
+
+ /**
* @param clientPackage
* @return true if this is keyguard package
*/
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 51c9619b77ca..827b88a5b61a 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -667,8 +667,8 @@ class ShortcutPackage extends ShortcutPackageItem {
// - version code hasn't change
// - lastUpdateTime hasn't change
// - all target activities are still enabled.
- if ((getPackageInfo().getVersionCode() >= pi.versionCode)
- && (getPackageInfo().getLastUpdateTime() >= pi.lastUpdateTime)
+ if ((getPackageInfo().getVersionCode() == pi.versionCode)
+ && (getPackageInfo().getLastUpdateTime() == pi.lastUpdateTime)
&& areAllActivitiesStillEnabled()) {
return false;
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 558467b2ef85..44df9264d748 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -2626,7 +2626,7 @@ public class ShortcutService extends IShortcutService.Stub {
synchronized (mLock) {
final ShortcutUser user = getUserShortcutsLocked(userId);
user.attemptToRestoreIfNeededAndSave(this, packageName, userId);
- user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ false);
+ user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ true);
}
verifyStates();
}
@@ -2641,7 +2641,7 @@ public class ShortcutService extends IShortcutService.Stub {
user.attemptToRestoreIfNeededAndSave(this, packageName, userId);
if (isPackageInstalled(packageName, userId)) {
- user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ false);
+ user.rescanPackageIfNeeded(packageName, /* forceRescan=*/ true);
}
}
verifyStates();
@@ -2863,7 +2863,10 @@ public class ShortcutService extends IShortcutService.Stub {
for (int i = list.size() - 1; i >= 0; i--) {
final PackageInfo pi = list.get(i);
- if (pi.lastUpdateTime >= lastScanTime) {
+ // If the package has been updated since the last scan time, then scan it.
+ // Also if it's a system app with no update, lastUpdateTime is not reliable, so
+ // just scan it.
+ if (pi.lastUpdateTime >= lastScanTime || isPureSystemApp(pi.applicationInfo)) {
if (DEBUG) {
Slog.d(TAG, "Found updated package " + pi.packageName);
}
@@ -2872,6 +2875,13 @@ public class ShortcutService extends IShortcutService.Stub {
}
}
+ /**
+ * @return true if it's a system app with no updates.
+ */
+ private boolean isPureSystemApp(ApplicationInfo ai) {
+ return ai.isSystemApp() && !ai.isUpdatedSystemApp();
+ }
+
private boolean isApplicationFlagSet(@NonNull String packageName, int userId, int flags) {
final ApplicationInfo ai = injectApplicationInfoWithUninstalled(packageName, userId);
return (ai != null) && ((ai.flags & flags) == flags);
diff --git a/services/tests/servicestests/assets/shortcut/shortcut_legacy_file.xml b/services/tests/servicestests/assets/shortcut/shortcut_legacy_file.xml
index 872dc3a26773..f7eee9155da4 100644
--- a/services/tests/servicestests/assets/shortcut/shortcut_legacy_file.xml
+++ b/services/tests/servicestests/assets/shortcut/shortcut_legacy_file.xml
@@ -16,7 +16,7 @@
<user locales="en-US" last-app-scan-time="3113976673">
<package name="com.android.test.1" call-count="0" last-reset="1468976368772">
<package-info version="25" last_udpate_time="1230796800000" />
- <shortcut id="manifest-shortcut-storage" activity="com.android.test.1/com.android.test.1.Settings" title="Storage" titleid="2131625197" titlename="storage_settings" textid="0" dmessageid="0" intent="#Intent;action=android.settings.INTERNAL_STORAGE_SETTINGS;end" timestamp="1469050672334" rank="4" flags="420" icon-res="2130837747" icon-resname="drawable/ic_shortcut_storage" >
+ <shortcut id="manifest-shortcut-storage" activity="com.android.test.1/com.android.test.1.Settings" title="Storage" intent="#Intent;action=android.settings.INTERNAL_STORAGE_SETTINGS;end" timestamp="1469050672334" flags="1" >
<intent-extras>
<int name="key" value="12345" />
</intent-extras>
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index b1c0ed44ba69..4bd0d6fb9b38 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -4149,28 +4149,7 @@ public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
ArgumentCaptor<List> shortcuts;
- // First, call the event without updating the versions.
- reset(c0);
- reset(c10);
-
- mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageUpdateIntent(CALLING_PACKAGE_1, USER_0));
- mService.mPackageMonitor.onReceive(getTestContext(),
- genPackageUpdateIntent(CALLING_PACKAGE_1, USER_10));
-
- waitOnMainThread();
-
- // Version not changed, so no callback.
- verify(c0, times(0)).onShortcutsChanged(
- eq(CALLING_PACKAGE_1),
- any(List.class),
- any(UserHandle.class));
- verify(c10, times(0)).onShortcutsChanged(
- eq(CALLING_PACKAGE_1),
- any(List.class),
- any(UserHandle.class));
-
- // Next, update the version info for package 1.
+ // Update the version info for package 1.
reset(c0);
reset(c10);
updatePackageVersion(CALLING_PACKAGE_1, 1);
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index a1d2b0f7712c..1cfb030ae218 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -510,6 +510,14 @@ public class IWindowManagerImpl implements IWindowManager {
}
@Override
+ public void setKeyguardAnimatingIn(boolean animating) throws RemoteException {
+ }
+
+ @Override
+ public void setSwitchingUser(boolean switching) throws RemoteException {
+ }
+
+ @Override
public void lockNow(Bundle options) {
// TODO Auto-generated method stub
}