diff options
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&lt;User&gt;"/> </data> </pre> <p class="caution"> @@ -945,9 +945,9 @@ android:transitionName='@{"image_" + id}' <import type="android.util.SparseArray"/> <import type="java.util.Map"/> <import type="java.util.List"/> - <variable name="list" type="List<String>"/> - <variable name="sparse" type="SparseArray<String>"/> - <variable name="map" type="Map<String, String>"/> + <variable name="list" type="List&lt;String&gt;"/> + <variable name="sparse" type="SparseArray&lt;String&gt;"/> + <variable name="map" type="Map&lt;String, String&gt;"/> <variable name="index" type="int"/> <variable name="key" type="String"/> </data> @@ -1247,7 +1247,7 @@ user.put("age", 17); <pre> <data> <import type="android.databinding.ObservableMap"/> - <variable name="user" type="ObservableMap<String, Object>"/> + <variable name="user" type="ObservableMap&lt;String, Object&gt;"/> </data> … <TextView @@ -1277,7 +1277,7 @@ user.add(17); <data> <import type="android.databinding.ObservableList"/> <import type="com.example.my.app.Fields"/> - <variable name="user" type="ObservableList<Object>"/> + <variable name="user" type="ObservableList&lt;Object&gt;"/> </data> … <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 & 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 & voice input settings (<em>Settings/Apps/Default - Apps/Assist & voice input</em>) + Figure 2. Assist & 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 } |