Merge changes I1bad66e2,Ibc93597e,Id985fc28 into nyc-dev
* changes: Remove the highlight on the overview button in the screen pinning dialog Fixing bad regression in alt-tab layout. Workaround to ensure that a SystemUI process is always available.
This commit is contained in:
@@ -184,6 +184,14 @@
|
||||
android:exported="true"
|
||||
/>
|
||||
|
||||
<!-- Recents depends on every user having their own SystemUI process, so on user switch,
|
||||
ensure that the process is created by starting this service.
|
||||
-->
|
||||
<service android:name="SystemUISecondaryUserService"
|
||||
android:exported="true"
|
||||
android:permission="com.android.systemui.permission.SELF" />
|
||||
|
||||
|
||||
<!-- started from PhoneWindowManager
|
||||
TODO: Should have an android:permission attribute -->
|
||||
<service android:name=".screenshot.TakeScreenshotService"
|
||||
|
||||
@@ -109,21 +109,6 @@
|
||||
android:paddingStart="@dimen/screen_pinning_request_frame_padding"
|
||||
android:paddingEnd="@dimen/screen_pinning_request_frame_padding" >
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scaleType="matrix"
|
||||
android:src="@drawable/screen_pinning_light_bg_circ" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingEnd="@dimen/screen_pinning_request_inner_padding"
|
||||
android:paddingStart="@dimen/screen_pinning_request_inner_padding"
|
||||
android:paddingTop="@dimen/screen_pinning_request_inner_padding"
|
||||
android:scaleType="matrix"
|
||||
android:src="@drawable/screen_pinning_bg_circ" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -40,21 +40,6 @@
|
||||
android:layout_width="@dimen/screen_pinning_request_button_height"
|
||||
android:layout_weight="0" >
|
||||
|
||||
<ImageView
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:scaleType="matrix"
|
||||
android:src="@drawable/screen_pinning_light_bg_circ" />
|
||||
|
||||
<ImageView
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:scaleType="matrix"
|
||||
android:paddingLeft="@dimen/screen_pinning_request_inner_padding"
|
||||
android:paddingTop="@dimen/screen_pinning_request_inner_padding"
|
||||
android:paddingBottom="@dimen/screen_pinning_request_inner_padding"
|
||||
android:src="@drawable/screen_pinning_bg_circ" />
|
||||
|
||||
<ImageView
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -178,7 +178,7 @@
|
||||
<!-- Recents: The relative range of visible tasks from the current scroll position
|
||||
while the stack is focused. -->
|
||||
<item name="recents_layout_focused_range_min" format="float" type="integer">-3</item>
|
||||
<item name="recents_layout_focused_range_max" format="float" type="integer">3</item>
|
||||
<item name="recents_layout_focused_range_max" format="float" type="integer">2</item>
|
||||
|
||||
<!-- Recents: The relative range of visible tasks from the current scroll position
|
||||
while the stack is not focused. -->
|
||||
|
||||
@@ -123,6 +123,17 @@ public class SystemUIApplication extends Application {
|
||||
startServicesIfNeeded(SERVICES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that all the Secondary user SystemUI services are running. If they are already
|
||||
* running, this is a no-op. This is needed to conditinally start all the services, as we only
|
||||
* need to have it in the main process.
|
||||
*
|
||||
* <p>This method must only be called from the main thread.</p>
|
||||
*/
|
||||
void startSecondaryUserServicesIfNeeded() {
|
||||
startServicesIfNeeded(SERVICES_PER_USER);
|
||||
}
|
||||
|
||||
private void startServicesIfNeeded(Class<?>[] services) {
|
||||
if (mServicesStarted) {
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.os.Process;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
public class SystemUISecondaryUserService extends Service {
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
((SystemUIApplication) getApplication()).startSecondaryUserServicesIfNeeded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
|
||||
SystemUI[] services = ((SystemUIApplication) getApplication()).getServices();
|
||||
if (args == null || args.length == 0) {
|
||||
for (SystemUI ui: services) {
|
||||
pw.println("dumping service: " + ui.getClass().getName());
|
||||
ui.dump(fd, pw, args);
|
||||
}
|
||||
} else {
|
||||
String svc = args[0];
|
||||
for (SystemUI ui: services) {
|
||||
String name = ui.getClass().getName();
|
||||
if (name.endsWith(svc)) {
|
||||
ui.dump(fd, pw, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +144,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
|
||||
// Task launching
|
||||
Rect mTaskStackBounds = new Rect();
|
||||
Rect mLastTaskViewBounds = new Rect();
|
||||
TaskViewTransform mTmpTransform = new TaskViewTransform();
|
||||
int mStatusBarHeight;
|
||||
int mNavBarHeight;
|
||||
@@ -169,8 +168,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
}
|
||||
});
|
||||
|
||||
protected Bitmap mThumbnailTransitionBitmapCache;
|
||||
Task mThumbnailTransitionBitmapCacheKey;
|
||||
protected Bitmap mThumbTransitionBitmapCache;
|
||||
|
||||
public RecentsImpl(Context context) {
|
||||
mContext = context;
|
||||
@@ -186,7 +184,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
|
||||
// Initialize the static configuration resources
|
||||
reloadHeaderBarLayout();
|
||||
updateHeaderBarLayout(null /* stack */);
|
||||
|
||||
// When we start, preload the data associated with the previous recent tasks.
|
||||
// We can use a new plan since the caches will be the same.
|
||||
@@ -201,12 +198,11 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
}
|
||||
|
||||
public void onBootCompleted() {
|
||||
updateHeaderBarLayout(null /* stack */);
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public void onConfigurationChanged() {
|
||||
reloadHeaderBarLayout();
|
||||
updateHeaderBarLayout(null /* stack */);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,9 +364,14 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
loader.preloadTasks(sInstanceLoadPlan, topTask.id, topTaskHome.value);
|
||||
TaskStack stack = sInstanceLoadPlan.getTaskStack();
|
||||
if (stack.getTaskCount() > 0) {
|
||||
// We try and draw the thumbnail transition bitmap in parallel before
|
||||
// toggle/show recents is called
|
||||
preCacheThumbnailTransitionBitmapAsync(topTask, stack, mDummyStackView);
|
||||
// Only preload the icon (but not the thumbnail since it may not have been taken for
|
||||
// the pausing activity)
|
||||
preloadIcon(topTask);
|
||||
|
||||
// At this point, we don't know anything about the stack state. So only calculate
|
||||
// the dimensions of the thumbnail that we need for the transition into Recents, but
|
||||
// do not draw it until we construct the activity options when we start Recents
|
||||
updateHeaderBarLayout(stack);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -601,21 +602,30 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
if (stack != null) {
|
||||
stackLayout.getTaskStackBounds(windowRect, systemInsets.top, systemInsets.right,
|
||||
mTaskStackBounds);
|
||||
stackLayout.reset();
|
||||
stackLayout.initialize(windowRect, mTaskStackBounds,
|
||||
TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack));
|
||||
mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */);
|
||||
}
|
||||
Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
|
||||
if (!taskViewBounds.equals(mLastTaskViewBounds)) {
|
||||
mLastTaskViewBounds.set(taskViewBounds);
|
||||
|
||||
Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds();
|
||||
int taskViewWidth = taskViewBounds.width();
|
||||
synchronized (mHeaderBarLock) {
|
||||
mHeaderBar.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(taskViewWidth, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(mTaskBarHeight, View.MeasureSpec.EXACTLY));
|
||||
if (mHeaderBar.getMeasuredWidth() != taskViewWidth ||
|
||||
mHeaderBar.getMeasuredHeight() != mTaskBarHeight) {
|
||||
mHeaderBar.measure(
|
||||
View.MeasureSpec.makeMeasureSpec(taskViewWidth, View.MeasureSpec.EXACTLY),
|
||||
View.MeasureSpec.makeMeasureSpec(mTaskBarHeight, View.MeasureSpec.EXACTLY));
|
||||
}
|
||||
mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight);
|
||||
}
|
||||
|
||||
// Update the transition bitmap to match the new header bar height
|
||||
if (mThumbTransitionBitmapCache == null ||
|
||||
(mThumbTransitionBitmapCache.getWidth() != taskViewWidth) ||
|
||||
(mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) {
|
||||
mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth,
|
||||
mTaskBarHeight, Bitmap.Config.ARGB_8888);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -651,40 +661,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
Recents.getTaskLoader().loadTasks(mContext, sInstanceLoadPlan, launchOpts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches the header thumbnail used for a window animation asynchronously into
|
||||
* {@link #mThumbnailTransitionBitmapCache}.
|
||||
*/
|
||||
private void preCacheThumbnailTransitionBitmapAsync(ActivityManager.RunningTaskInfo topTask,
|
||||
TaskStack stack, TaskStackView stackView) {
|
||||
preloadIcon(topTask);
|
||||
|
||||
// Update the header bar if necessary
|
||||
updateHeaderBarLayout(stack);
|
||||
|
||||
// Update the destination rect
|
||||
final Task toTask = new Task();
|
||||
final TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask);
|
||||
ForegroundThread.getHandler().postAtFrontOfQueue(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final Bitmap transitionBitmap = drawThumbnailTransitionBitmap(toTask, toTransform);
|
||||
if (transitionBitmap != null) {
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mThumbnailTransitionBitmapCache = transitionBitmap;
|
||||
mThumbnailTransitionBitmapCacheKey = toTask;
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Log.e(TAG, "Could not load thumbnail for task: " + toTask + " at transform: " +
|
||||
toTransform);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the activity options for a unknown state->recents transition.
|
||||
*/
|
||||
@@ -724,9 +700,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
if (task.isFreeformTask()) {
|
||||
mTmpTransform = stackLayout.getStackTransformScreenCoordinates(task,
|
||||
stackScroller.getStackScroll(), mTmpTransform, null);
|
||||
Bitmap thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform,
|
||||
mThumbTransitionBitmapCache);
|
||||
Rect toTaskRect = new Rect();
|
||||
mTmpTransform.rect.round(toTaskRect);
|
||||
Bitmap thumbnail = getThumbnailBitmap(topTask, task, mTmpTransform);
|
||||
specs.add(new AppTransitionAnimationSpec(task.key.id, thumbnail, toTaskRect));
|
||||
}
|
||||
}
|
||||
@@ -738,9 +715,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
// Update the destination rect
|
||||
Task toTask = new Task();
|
||||
TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask);
|
||||
RectF toTaskRect = toTransform.rect;
|
||||
Bitmap thumbnail = getThumbnailBitmap(topTask, toTask, toTransform);
|
||||
Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform,
|
||||
mThumbTransitionBitmapCache);
|
||||
if (thumbnail != null) {
|
||||
RectF toTaskRect = toTransform.rect;
|
||||
return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
|
||||
thumbnail, (int) toTaskRect.left, (int) toTaskRect.top,
|
||||
(int) toTaskRect.width(), (int) toTaskRect.height(), mHandler, null);
|
||||
@@ -750,22 +728,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap getThumbnailBitmap(ActivityManager.RunningTaskInfo topTask, Task toTask,
|
||||
TaskViewTransform toTransform) {
|
||||
Bitmap thumbnail;
|
||||
if (mThumbnailTransitionBitmapCacheKey != null
|
||||
&& mThumbnailTransitionBitmapCacheKey.key != null
|
||||
&& mThumbnailTransitionBitmapCacheKey.key.equals(toTask.key)) {
|
||||
thumbnail = mThumbnailTransitionBitmapCache;
|
||||
mThumbnailTransitionBitmapCacheKey = null;
|
||||
mThumbnailTransitionBitmapCache = null;
|
||||
} else {
|
||||
preloadIcon(topTask);
|
||||
thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform);
|
||||
}
|
||||
return thumbnail;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the transition rect for the given task id.
|
||||
*/
|
||||
@@ -793,26 +755,19 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
/**
|
||||
* Draws the header of a task used for the window animation into a bitmap.
|
||||
*/
|
||||
private Bitmap drawThumbnailTransitionBitmap(Task toTask, TaskViewTransform toTransform) {
|
||||
private Bitmap drawThumbnailTransitionBitmap(Task toTask, TaskViewTransform toTransform,
|
||||
Bitmap thumbnail) {
|
||||
SystemServicesProxy ssp = Recents.getSystemServices();
|
||||
if (toTransform != null && toTask.key != null) {
|
||||
Bitmap thumbnail;
|
||||
synchronized (mHeaderBarLock) {
|
||||
int toHeaderWidth = (int) toTransform.rect.width();
|
||||
int toHeaderHeight = (int) (mHeaderBar.getMeasuredHeight() * toTransform.scale);
|
||||
if (toHeaderWidth <= 0 || toHeaderHeight <= 0) {
|
||||
return null;
|
||||
}
|
||||
boolean disabledInSafeMode = !toTask.isSystemApp && ssp.isInSafeMode();
|
||||
mHeaderBar.onTaskViewSizeChanged((int) toTransform.rect.width(),
|
||||
(int) toTransform.rect.height());
|
||||
thumbnail = Bitmap.createBitmap(toHeaderWidth, toHeaderHeight,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) {
|
||||
thumbnail.eraseColor(0xFFff0000);
|
||||
} else {
|
||||
thumbnail.eraseColor(0);
|
||||
Canvas c = new Canvas(thumbnail);
|
||||
c.scale(toTransform.scale, toTransform.scale);
|
||||
// Workaround for b/27815919, reset the callback so that we do not trigger an
|
||||
// invalidate on the header bar as a result of updating the icon
|
||||
Drawable icon = mHeaderBar.getIconView().getDrawable();
|
||||
@@ -854,6 +809,18 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
boolean hasRecentTasks = stack.getTaskCount() > 0;
|
||||
boolean useThumbnailTransition = (topTask != null) && !isTopTaskHome && hasRecentTasks;
|
||||
|
||||
// Update the launch state that we need in updateHeaderBarLayout()
|
||||
launchState.launchedFromHome = !useThumbnailTransition;
|
||||
launchState.launchedFromApp = useThumbnailTransition || mLaunchedWhileDocking;
|
||||
launchState.launchedViaDockGesture = mLaunchedWhileDocking;
|
||||
launchState.launchedViaDragGesture = mDraggingInRecents;
|
||||
launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
|
||||
launchState.launchedWithAltTab = mTriggeredFromAltTab;
|
||||
|
||||
// Preload the icon (this will be a null-op if we have preloaded the icon already in
|
||||
// preloadRecents())
|
||||
preloadIcon(topTask);
|
||||
|
||||
// Update the header bar if necessary
|
||||
updateHeaderBarLayout(stack);
|
||||
|
||||
@@ -861,44 +828,27 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener
|
||||
TaskStackLayoutAlgorithm.VisibilityReport stackVr =
|
||||
mDummyStackView.computeStackVisibilityReport();
|
||||
|
||||
// Update the launch state
|
||||
launchState.launchedFromHome = false;
|
||||
launchState.launchedFromApp = mLaunchedWhileDocking;
|
||||
launchState.launchedViaDockGesture = mLaunchedWhileDocking;
|
||||
launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1;
|
||||
launchState.launchedWithAltTab = mTriggeredFromAltTab;
|
||||
// Update the remaining launch state
|
||||
launchState.launchedNumVisibleTasks = stackVr.numVisibleTasks;
|
||||
launchState.launchedNumVisibleThumbnails = stackVr.numVisibleThumbnails;
|
||||
launchState.launchedViaDragGesture = mDraggingInRecents;
|
||||
|
||||
if (!animate) {
|
||||
startRecentsActivity(ActivityOptions.makeCustomAnimation(mContext, -1, -1));
|
||||
return;
|
||||
}
|
||||
|
||||
ActivityOptions opts;
|
||||
if (useThumbnailTransition) {
|
||||
launchState.launchedFromApp = true;
|
||||
|
||||
// Try starting with a thumbnail transition
|
||||
ActivityOptions opts = getThumbnailTransitionActivityOptions(topTask, mDummyStackView);
|
||||
if (opts != null) {
|
||||
startRecentsActivity(opts);
|
||||
} else {
|
||||
// Fall through below to the non-thumbnail transition
|
||||
useThumbnailTransition = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!useThumbnailTransition) {
|
||||
launchState.launchedFromHome = true;
|
||||
|
||||
opts = getThumbnailTransitionActivityOptions(topTask, mDummyStackView);
|
||||
} else {
|
||||
// If there is no thumbnail transition, but is launching from home into recents, then
|
||||
// use a quick home transition
|
||||
ActivityOptions opts = hasRecentTasks
|
||||
? getHomeTransitionActivityOptions()
|
||||
: getUnknownTransitionActivityOptions();
|
||||
startRecentsActivity(opts);
|
||||
opts = hasRecentTasks
|
||||
? getHomeTransitionActivityOptions()
|
||||
: getUnknownTransitionActivityOptions();
|
||||
}
|
||||
startRecentsActivity(opts);
|
||||
mLastToggleTime = SystemClock.elapsedRealtime();
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ public class RecentsTvImpl extends RecentsImpl{
|
||||
*/
|
||||
private ActivityOptions getThumbnailTransitionActivityOptionsForTV(
|
||||
ActivityManager.RunningTaskInfo topTask) {
|
||||
Bitmap thumbnail = mThumbnailTransitionBitmapCache;
|
||||
Bitmap thumbnail = mThumbTransitionBitmapCache;
|
||||
Rect rect = TaskCardView.getStartingCardThumbnailRect(mContext);
|
||||
if (thumbnail != null) {
|
||||
return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView,
|
||||
|
||||
@@ -456,7 +456,8 @@ public class TaskStackAnimationHelper {
|
||||
TaskStack stack = mStackView.getStack();
|
||||
|
||||
final float curScroll = stackScroller.getStackScroll();
|
||||
final float newScroll = stackLayout.getStackScrollForTask(newFocusedTask);
|
||||
final float newScroll = stackScroller.getBoundedStackScroll(
|
||||
stackLayout.getStackScrollForTask(newFocusedTask));
|
||||
boolean willScrollToFront = newScroll > curScroll;
|
||||
boolean willScroll = Float.compare(newScroll, curScroll) != 0;
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ import android.view.ViewDebug;
|
||||
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.recents.Recents;
|
||||
import com.android.systemui.recents.RecentsActivity;
|
||||
import com.android.systemui.recents.RecentsActivityLaunchState;
|
||||
import com.android.systemui.recents.RecentsConfiguration;
|
||||
import com.android.systemui.recents.RecentsDebugFlags;
|
||||
@@ -530,8 +531,12 @@ public class TaskStackLayoutAlgorithm {
|
||||
? stack.indexOfStackTask(launchTask)
|
||||
: mNumStackTasks - 1;
|
||||
if (getInitialFocusState() == STATE_FOCUSED) {
|
||||
int maxBottomOffset = mStackBottomOffset + mTaskRect.height();
|
||||
float maxBottomNormX = getNormalizedXFromFocusedY(maxBottomOffset, FROM_BOTTOM);
|
||||
mFocusedRange.offset(0f);
|
||||
mMinScrollP = 0;
|
||||
mMaxScrollP = Math.max(mMinScrollP, mNumStackTasks - 1);
|
||||
mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) -
|
||||
Math.max(0, mFocusedRange.getAbsoluteX(maxBottomNormX)));
|
||||
if (launchState.launchedFromHome) {
|
||||
mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
|
||||
} else {
|
||||
@@ -555,7 +560,10 @@ public class TaskStackLayoutAlgorithm {
|
||||
Math.max(0, mUnfocusedRange.getAbsoluteX(maxBottomNormX)));
|
||||
boolean scrollToFront = launchState.launchedFromHome ||
|
||||
launchState.launchedViaDockGesture;
|
||||
if (scrollToFront) {
|
||||
if (launchState.launchedWithAltTab) {
|
||||
mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
|
||||
mInitialNormX = null;
|
||||
} else if (scrollToFront) {
|
||||
mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP);
|
||||
mInitialNormX = null;
|
||||
} else {
|
||||
@@ -652,8 +660,9 @@ public class TaskStackLayoutAlgorithm {
|
||||
* Returns the default focus state.
|
||||
*/
|
||||
public int getInitialFocusState() {
|
||||
RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState();
|
||||
RecentsDebugFlags debugFlags = Recents.getDebugFlags();
|
||||
if (debugFlags.isPagingEnabled()) {
|
||||
if (debugFlags.isPagingEnabled() || launchState.launchedWithAltTab) {
|
||||
return STATE_FOCUSED;
|
||||
} else {
|
||||
return STATE_UNFOCUSED;
|
||||
@@ -1026,6 +1035,18 @@ public class TaskStackLayoutAlgorithm {
|
||||
return mUnfocusedCurveInterpolator.getX(offsetPct);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the normalized x on the focused curve given an absolute Y position (relative to the
|
||||
* stack height).
|
||||
*/
|
||||
private float getNormalizedXFromFocusedY(float y, @AnchorSide int fromSide) {
|
||||
float offset = (fromSide == FROM_TOP)
|
||||
? mStackRect.height() - y
|
||||
: y;
|
||||
float offsetPct = offset / mStackRect.height();
|
||||
return mFocusedCurveInterpolator.getX(offsetPct);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new path for the focused curve.
|
||||
*/
|
||||
@@ -1036,10 +1057,13 @@ public class TaskStackLayoutAlgorithm {
|
||||
float topPeekHeightPct = (float) mFocusedTopPeekHeight / mStackRect.height();
|
||||
float bottomPeekHeightPct = (float) (mStackBottomOffset + mFocusedBottomPeekHeight) /
|
||||
mStackRect.height();
|
||||
float minBottomPeekHeightPct = (float) (mFocusedTopPeekHeight + mTaskRect.height() -
|
||||
mMinMargin) / mStackRect.height();
|
||||
Path p = new Path();
|
||||
p.moveTo(0f, 1f);
|
||||
p.lineTo(0.5f, 1f - topPeekHeightPct);
|
||||
p.lineTo(1f - (0.5f / mFocusedRange.relativeMax), bottomPeekHeightPct);
|
||||
p.lineTo(1f - (0.5f / mFocusedRange.relativeMax), Math.max(1f - minBottomPeekHeightPct,
|
||||
bottomPeekHeightPct));
|
||||
p.lineTo(1f, 0f);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@@ -52,6 +53,7 @@ import com.android.settingslib.RestrictedLockUtils;
|
||||
import com.android.systemui.BitmapHelper;
|
||||
import com.android.systemui.GuestResumeSessionReceiver;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SystemUISecondaryUserService;
|
||||
import com.android.systemui.qs.QSTile;
|
||||
import com.android.systemui.qs.tiles.UserDetailView;
|
||||
import com.android.systemui.statusbar.phone.ActivityStarter;
|
||||
@@ -101,6 +103,8 @@ public class UserSwitcherController {
|
||||
private boolean mSimpleUserSwitcher;
|
||||
private boolean mAddUsersWhenLocked;
|
||||
private boolean mPauseRefreshUsers;
|
||||
private int mSecondaryUser = UserHandle.USER_NULL;
|
||||
private Intent mSecondaryUserServiceIntent;
|
||||
private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2);
|
||||
|
||||
public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor,
|
||||
@@ -121,6 +125,8 @@ public class UserSwitcherController {
|
||||
mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter,
|
||||
null /* permission */, null /* scheduler */);
|
||||
|
||||
mSecondaryUserServiceIntent = new Intent(context, SystemUISecondaryUserService.class);
|
||||
|
||||
filter = new IntentFilter();
|
||||
filter.addAction(ACTION_REMOVE_GUEST);
|
||||
filter.addAction(ACTION_LOGOUT_USER);
|
||||
@@ -477,6 +483,20 @@ public class UserSwitcherController {
|
||||
}
|
||||
notifyAdapters();
|
||||
|
||||
// Disconnect from the old secondary user's service
|
||||
if (mSecondaryUser != UserHandle.USER_NULL) {
|
||||
context.stopServiceAsUser(mSecondaryUserServiceIntent,
|
||||
UserHandle.of(mSecondaryUser));
|
||||
mSecondaryUser = UserHandle.USER_NULL;
|
||||
}
|
||||
// Connect to the new secondary user's service (purely to ensure that a persistent
|
||||
// SystemUI application is created for that user)
|
||||
if (userInfo != null && !userInfo.isPrimary()) {
|
||||
context.startServiceAsUser(mSecondaryUserServiceIntent,
|
||||
UserHandle.of(userInfo.id));
|
||||
mSecondaryUser = userInfo.id;
|
||||
}
|
||||
|
||||
if (UserManager.isSplitSystemUser() && userInfo != null && !userInfo.isGuest()
|
||||
&& userInfo.id != UserHandle.USER_SYSTEM) {
|
||||
showLogoutNotification(currentId);
|
||||
|
||||
Reference in New Issue
Block a user