diff options
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui')
13 files changed, 288 insertions, 317 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 001d660..dd28734 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -637,7 +637,7 @@ public class KeyguardViewMediator extends SystemUI { doKeyguardLocked(null); } } - KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurndOff(why); + KeyguardUpdateMonitor.getInstance(mContext).dispatchScreenTurnedOff(why); } private void doKeyguardLaterLocked() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java index 5c1a317..cb78deb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java @@ -17,7 +17,6 @@ package com.android.systemui.qs.tiles; import android.app.ActivityManager; -import android.os.SystemClock; import com.android.systemui.R; import com.android.systemui.qs.QSTile; @@ -27,16 +26,11 @@ import com.android.systemui.statusbar.policy.FlashlightController; public class FlashlightTile extends QSTile<QSTile.BooleanState> implements FlashlightController.FlashlightListener { - /** Grace period for which we consider the flashlight - * still available because it was recently on. */ - private static final long RECENTLY_ON_DURATION_MILLIS = 500; - private final AnimationIcon mEnable = new AnimationIcon(R.drawable.ic_signal_flashlight_enable_animation); private final AnimationIcon mDisable = new AnimationIcon(R.drawable.ic_signal_flashlight_disable_animation); private final FlashlightController mFlashlightController; - private long mWasLastOn; public FlashlightTile(Host host) { super(host); @@ -69,33 +63,17 @@ public class FlashlightTile extends QSTile<QSTile.BooleanState> implements return; } boolean newState = !mState.value; - mFlashlightController.setFlashlight(newState); refreshState(newState ? UserBoolean.USER_TRUE : UserBoolean.USER_FALSE); + mFlashlightController.setFlashlight(newState); } @Override protected void handleUpdateState(BooleanState state, Object arg) { - if (state.value) { - mWasLastOn = SystemClock.uptimeMillis(); - } - + state.visible = mFlashlightController.isAvailable(); + state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label); if (arg instanceof UserBoolean) { state.value = ((UserBoolean) arg).value; } - - if (!state.value && mWasLastOn != 0) { - if (SystemClock.uptimeMillis() > mWasLastOn + RECENTLY_ON_DURATION_MILLIS) { - mWasLastOn = 0; - } else { - mHandler.removeCallbacks(mRecentlyOnTimeout); - mHandler.postAtTime(mRecentlyOnTimeout, mWasLastOn + RECENTLY_ON_DURATION_MILLIS); - } - } - - // Always show the tile when the flashlight is or was recently on. This is needed because - // the camera is not available while it is being used for the flashlight. - state.visible = mWasLastOn != 0 || mFlashlightController.isAvailable(); - state.label = mHost.getContext().getString(R.string.quick_settings_flashlight_label); final AnimationIcon icon = state.value ? mEnable : mDisable; icon.setAllowAnimation(arg instanceof UserBoolean && ((UserBoolean) arg).userInitiated); state.icon = icon; @@ -115,8 +93,8 @@ public class FlashlightTile extends QSTile<QSTile.BooleanState> implements } @Override - public void onFlashlightOff() { - refreshState(UserBoolean.BACKGROUND_FALSE); + public void onFlashlightChanged(boolean enabled) { + refreshState(enabled ? UserBoolean.BACKGROUND_TRUE : UserBoolean.BACKGROUND_FALSE); } @Override @@ -128,11 +106,4 @@ public class FlashlightTile extends QSTile<QSTile.BooleanState> implements public void onFlashlightAvailabilityChanged(boolean available) { refreshState(); } - - private Runnable mRecentlyOnTimeout = new Runnable() { - @Override - public void run() { - refreshState(); - } - }; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index 9dd82fc..2d1fab0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -42,6 +42,7 @@ import android.view.View; import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SystemUI; +import com.android.systemui.SystemUIApplication; import com.android.systemui.recents.misc.Console; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.model.RecentsTaskLoadPlan; @@ -53,6 +54,7 @@ import com.android.systemui.recents.views.TaskStackView; import com.android.systemui.recents.views.TaskStackViewLayoutAlgorithm; import com.android.systemui.recents.views.TaskViewHeader; import com.android.systemui.recents.views.TaskViewTransform; +import com.android.systemui.statusbar.phone.PhoneStatusBar; import java.util.ArrayList; import java.util.concurrent.atomic.AtomicBoolean; @@ -79,6 +81,8 @@ public class Recents extends SystemUI // Owner proxy events final public static String ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER = "action_notify_recents_visibility_change"; + final public static String ACTION_PROXY_SCREEN_PINNING_REQUEST_TO_OWNER = + "action_screen_pinning_request"; final public static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation"; final public static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity"; @@ -148,6 +152,9 @@ public class Recents extends SystemUI case ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER: visibilityChanged(intent.getBooleanExtra(EXTRA_RECENTS_VISIBILITY, false)); break; + case ACTION_PROXY_SCREEN_PINNING_REQUEST_TO_OWNER: + onStartScreenPinning(context); + break; } } } @@ -234,6 +241,7 @@ public class Recents extends SystemUI mProxyBroadcastReceiver = new RecentsOwnerEventProxyReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction(Recents.ACTION_PROXY_NOTIFY_RECENTS_VISIBLITY_TO_OWNER); + filter.addAction(Recents.ACTION_PROXY_SCREEN_PINNING_REQUEST_TO_OWNER); mContext.registerReceiverAsUser(mProxyBroadcastReceiver, UserHandle.CURRENT, filter, null, mHandler); } @@ -377,7 +385,7 @@ public class Recents extends SystemUI } // Return early if there are no tasks in the focused stack - if (focusedStack.getTaskCount() == 0) return; + if (focusedStack == null || focusedStack.getTaskCount() == 0) return; ActivityManager.RunningTaskInfo runningTask = mSystemServicesProxy.getTopMostTask(); // Return early if there is no running task (can't determine affiliated tasks in this case) @@ -801,6 +809,27 @@ public class Recents extends SystemUI } } + /** Notifies the status bar to trigger screen pinning. */ + @ProxyFromAnyToPrimaryUser + public static void startScreenPinning(Context context, SystemServicesProxy ssp) { + if (ssp.isForegroundUserOwner()) { + onStartScreenPinning(context); + } else { + Intent intent = createLocalBroadcastIntent(context, + ACTION_PROXY_SCREEN_PINNING_REQUEST_TO_OWNER); + context.sendBroadcastAsUser(intent, UserHandle.OWNER); + } + } + static void onStartScreenPinning(Context context) { + // For the primary user, the context for the SystemUI component is the SystemUIApplication + SystemUIApplication app = (SystemUIApplication) + getInstanceAndStartIfNeeded(context).mContext; + PhoneStatusBar statusBar = app.getComponent(PhoneStatusBar.class); + if (statusBar != null) { + statusBar.showScreenPinningRequest(false); + } + } + /** * Returns the preloaded load plan and invalidates it. */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 1248672..f014f09 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -85,8 +85,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView // Runnables to finish the Recents activity FinishRecentsRunnable mFinishLaunchHomeRunnable; - private PhoneStatusBar mStatusBar; - /** * A common Runnable to finish Recents either by calling finish() (with a custom animation) or * launching Home with some ActivityOptions. Generally we always launch home when we exit @@ -381,8 +379,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView mEmptyViewStub = (ViewStub) findViewById(R.id.empty_view_stub); mDebugOverlayStub = (ViewStub) findViewById(R.id.debug_overlay_stub); mScrimViews = new SystemBarScrimViews(this, mConfig); - mStatusBar = ((SystemUIApplication) getApplication()) - .getComponent(PhoneStatusBar.class); inflateDebugOverlay(); // Bind the search app widget when we first start up @@ -596,14 +592,14 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView private RecentsResizeTaskDialog getResizeTaskDebugDialog() { if (mResizeTaskDebugDialog == null) { - mResizeTaskDebugDialog = new RecentsResizeTaskDialog(getFragmentManager()); + mResizeTaskDebugDialog = new RecentsResizeTaskDialog(getFragmentManager(), this); } return mResizeTaskDebugDialog; } @Override public void onTaskResize(Task t) { - getResizeTaskDebugDialog().showResizeTaskDialog(t); + getResizeTaskDebugDialog().showResizeTaskDialog(t, mRecentsView); } /**** RecentsView.RecentsViewCallbacks Implementation ****/ @@ -631,9 +627,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView @Override public void onScreenPinningRequest() { - if (mStatusBar != null) { - mStatusBar.showScreenPinningRequest(false); - } + RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); + SystemServicesProxy ssp = loader.getSystemServicesProxy(); + Recents.startScreenPinning(this, ssp); } /**** RecentsAppWidgetHost.RecentsAppWidgetHostCallbacks Implementation ****/ diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java index 9263543..abeb2b0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java @@ -292,7 +292,7 @@ public class RecentsConfiguration { Settings.Global.DEVELOPMENT_SETTINGS_ENABLED) != 0; lockToAppEnabled = ssp.getSystemSetting(context, Settings.System.LOCK_TO_APP_ENABLED) != 0; - multiStackEnabled = "1".equals(ssp.getSystemProperty("overview.enableMultiStack")); + multiStackEnabled = "true".equals(ssp.getSystemProperty("persist.sys.debug.multi_window")); } /** Called when the configuration has changed, and we want to reset any configuration specific diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java index d67eceb..7c11894 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java @@ -16,31 +16,23 @@ package com.android.systemui.recents; -import android.app.ActivityManager; import android.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; import android.app.FragmentManager; -import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; -import android.content.Intent; -import android.content.pm.ActivityInfo; -import android.content.pm.ResolveInfo; import android.graphics.Rect; import android.os.Bundle; -import android.util.MutableInt; -import android.util.SparseArray; import android.view.LayoutInflater; import android.view.View; -import android.widget.EditText; -import android.widget.Toast; +import android.widget.Button; import com.android.systemui.R; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.recents.model.Task; - -import java.util.List; +import com.android.systemui.recents.RecentsActivity; +import com.android.systemui.recents.views.RecentsView; /** * A helper for the dialogs that show when task debugging is on. @@ -49,80 +41,137 @@ public class RecentsResizeTaskDialog extends DialogFragment { static final String TAG = "RecentsResizeTaskDialog"; - // The task we want to resize. - Task mTaskToResize; - FragmentManager mFragmentManager; - View mResizeTaskDialogContent; + // The various window arrangements we can handle. + private static final int PLACE_LEFT = 1; + private static final int PLACE_RIGHT = 2; + private static final int PLACE_TOP = 3; + private static final int PLACE_BOTTOM = 4; + private static final int PLACE_FULL = 5; - public RecentsResizeTaskDialog() {} + // The task we want to resize. + private Task mTaskToResize; + private Task mNextTaskToResize; + private FragmentManager mFragmentManager; + private View mResizeTaskDialogContent; + private RecentsActivity mRecentsActivity; + private RecentsView mRecentsView; + private SystemServicesProxy mSsp; - public RecentsResizeTaskDialog(FragmentManager mgr) { + public RecentsResizeTaskDialog(FragmentManager mgr, RecentsActivity activity) { mFragmentManager = mgr; + mRecentsActivity = activity; + mSsp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); } /** Shows the resize-task dialog. */ - void showResizeTaskDialog(Task t) { - mTaskToResize = t; + void showResizeTaskDialog(Task mainTask, RecentsView rv) { + mTaskToResize = mainTask; + mRecentsView = rv; + mNextTaskToResize = mRecentsView.getNextTaskOrTopTask(mainTask); + show(mFragmentManager, TAG); } /** Creates a new resize-task dialog. */ private void createResizeTaskDialog(final Context context, LayoutInflater inflater, - AlertDialog.Builder builder, final SystemServicesProxy ssp) { - builder.setTitle("Resize Task - Enter new dimensions"); + AlertDialog.Builder builder) { + builder.setTitle(R.string.recents_caption_resize); mResizeTaskDialogContent = - inflater.inflate(R.layout.recents_multistack_stack_size_dialog, null, false); - Rect bounds = ssp.getTaskBounds(mTaskToResize.key.stackId); - setDimensionInEditText(mResizeTaskDialogContent, R.id.inset_left, bounds.left); - setDimensionInEditText(mResizeTaskDialogContent, R.id.inset_top, bounds.top); - setDimensionInEditText(mResizeTaskDialogContent, R.id.inset_right, bounds.right); - setDimensionInEditText(mResizeTaskDialogContent, R.id.inset_bottom, bounds.bottom); - builder.setView(mResizeTaskDialogContent); - builder.setPositiveButton("Resize Task", new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - int left = getDimensionFromEditText(mResizeTaskDialogContent, R.id.inset_left); - int top = getDimensionFromEditText(mResizeTaskDialogContent, R.id.inset_top); - int right = getDimensionFromEditText(mResizeTaskDialogContent, R.id.inset_right); - int bottom = getDimensionFromEditText(mResizeTaskDialogContent, R.id.inset_bottom); - if (bottom <= top || right <= left) { - Toast.makeText(context, "Invalid dimensions", Toast.LENGTH_SHORT).show(); - dismiss(); - return; - } - ssp.resizeTask(mTaskToResize.key.id, new Rect(left, top, right, bottom)); - dismiss(); + inflater.inflate(R.layout.recents_task_resize_dialog, null, false); + + ((Button)mResizeTaskDialogContent.findViewById(R.id.place_left)).setOnClickListener( + new View.OnClickListener() { + public void onClick(View v) { + placeTasks(PLACE_LEFT); + } + }); + ((Button)mResizeTaskDialogContent.findViewById(R.id.place_right)).setOnClickListener( + new View.OnClickListener() { + public void onClick(View v) { + placeTasks(PLACE_RIGHT); + } + }); + ((Button)mResizeTaskDialogContent.findViewById(R.id.place_top)).setOnClickListener( + new View.OnClickListener() { + public void onClick(View v) { + placeTasks(PLACE_TOP); } }); - builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { + ((Button)mResizeTaskDialogContent.findViewById(R.id.place_bottom)).setOnClickListener( + new View.OnClickListener() { + public void onClick(View v) { + placeTasks(PLACE_BOTTOM); + } + }); + ((Button)mResizeTaskDialogContent.findViewById(R.id.place_full)).setOnClickListener( + new View.OnClickListener() { + public void onClick(View v) { + placeTasks(PLACE_FULL); + } + }); + + builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dismiss(); } }); + + builder.setView(mResizeTaskDialogContent); } - /** Helper to get an integer value from an edit text. */ - private int getDimensionFromEditText(View container, int id) { - String text = ((EditText) container.findViewById(id)).getText().toString(); - if (text.trim().length() != 0) { - return Integer.parseInt(text.trim()); + /** Helper function to place window(s) on the display according to an arrangement request. */ + private void placeTasks(int arrangement) { + Rect focusedBounds = mSsp.getWindowRect(); + Rect otherBounds = new Rect(focusedBounds); + + switch (arrangement) { + case PLACE_LEFT: + focusedBounds.right = focusedBounds.centerX(); + otherBounds.left = focusedBounds.right; + break; + case PLACE_RIGHT: + otherBounds.right = otherBounds.centerX(); + focusedBounds.left = otherBounds.right; + break; + case PLACE_TOP: + focusedBounds.bottom = focusedBounds.centerY(); + otherBounds.top = focusedBounds.bottom; + break; + case PLACE_BOTTOM: + otherBounds.bottom = otherBounds.centerY(); + focusedBounds.top = otherBounds.bottom; + break; + case PLACE_FULL: + // Null the rectangle to avoid the other task to show up. + otherBounds = new Rect(); + break; } - return 0; - } - /** Helper to set an integer value to an edit text. */ - private void setDimensionInEditText(View container, int id, int value) { - ((EditText) container.findViewById(id)).setText("" + value); + // Resize all other tasks to go to the other side. + if (mNextTaskToResize != null && !otherBounds.isEmpty()) { + mSsp.resizeTask(mNextTaskToResize.key.id, otherBounds); + } + mSsp.resizeTask(mTaskToResize.key.id, focusedBounds); + + // Get rid of the dialog. + dismiss(); + mRecentsActivity.dismissRecentsToHomeRaw(false); + + // Show tasks - beginning with the other first so that the focus ends on the selected one. + // TODO: Remove this once issue b/19893373 is resolved. + if (mNextTaskToResize != null && !otherBounds.isEmpty()) { + mRecentsView.launchTask(mNextTaskToResize); + } + mRecentsView.launchTask(mTaskToResize); } @Override public Dialog onCreateDialog(Bundle args) { final Context context = this.getActivity(); - final SystemServicesProxy ssp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); LayoutInflater inflater = getActivity().getLayoutInflater(); AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - createResizeTaskDialog(context, inflater, builder, ssp); + createResizeTaskDialog(context, inflater, builder); return builder.create(); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index a473a29..d60df9c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -259,7 +259,7 @@ public class SystemServicesProxy { public Rect getTaskBounds(int stackId) { ActivityManager.StackInfo info = getAllStackInfos().get(stackId); if (info != null) - return getAllStackInfos().get(stackId).bounds; + return info.bounds; return new Rect(); } 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 448a7a9..abed7a5 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -149,6 +149,31 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV return mTaskStackViews; } + /** Gets the next task in the stack - or if the last - the top task */ + public Task getNextTaskOrTopTask(Task taskToSearch) { + Task returnTask = null; + boolean found = false; + List<TaskStackView> stackViews = getTaskStackViews(); + int stackCount = stackViews.size(); + for (int i = stackCount - 1; i >= 0; --i) { + TaskStack stack = stackViews.get(i).getStack(); + ArrayList<Task> taskList = stack.getTasks(); + // Iterate the stack views and try and find the focused task + for (int j = taskList.size() - 1; j >= 0; --j) { + Task task = taskList.get(j); + // Return the next task in the line. + if (found) + return task; + // Remember the first possible task as the top task. + if (returnTask == null) + returnTask = task; + if (task == taskToSearch) + found = true; + } + } + return returnTask; + } + /** Launches the focused task from the first stack if possible */ public boolean launchFocusedTask() { // Get the first stack view @@ -172,6 +197,28 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV return false; } + /** Launches a given task. */ + public boolean launchTask(Task task) { + // Get the first stack view + List<TaskStackView> stackViews = getTaskStackViews(); + int stackCount = stackViews.size(); + for (int i = 0; i < stackCount; i++) { + TaskStackView stackView = stackViews.get(i); + TaskStack stack = stackView.getStack(); + // Iterate the stack views and try and find the given task. + List<TaskView> taskViews = stackView.getTaskViews(); + int taskViewCount = taskViews.size(); + for (int j = 0; j < taskViewCount; j++) { + TaskView tv = taskViews.get(j); + if (tv.getTask() == task) { + onTaskViewClicked(stackView, tv, stack, task, false); + return true; + } + } + } + return false; + } + /** Launches the task that Recents was launched from, if possible */ public boolean launchPreviousTask() { // Get the first stack view diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java index ca08319..42399a3 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java @@ -26,14 +26,15 @@ import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Canvas; import android.graphics.Color; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.RippleDrawable; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffXfermode; -import android.graphics.drawable.Drawable; -import android.graphics.drawable.GradientDrawable; -import android.graphics.drawable.RippleDrawable; +import android.graphics.Rect; import android.util.AttributeSet; import android.view.View; import android.view.ViewOutlineProvider; @@ -43,7 +44,9 @@ import android.widget.TextView; import com.android.systemui.R; import com.android.systemui.recents.Constants; import com.android.systemui.recents.RecentsConfiguration; +import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.Utilities; +import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.recents.model.Task; @@ -51,6 +54,7 @@ import com.android.systemui.recents.model.Task; public class TaskViewHeader extends FrameLayout { RecentsConfiguration mConfig; + private SystemServicesProxy mSsp; // Header views ImageView mMoveTaskButton; @@ -91,6 +95,7 @@ public class TaskViewHeader extends FrameLayout { public TaskViewHeader(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mConfig = RecentsConfiguration.getInstance(); + mSsp = RecentsTaskLoader.getInstance().getSystemServicesProxy(); setWillNotDraw(false); setClipToOutline(true); setOutlineProvider(new ViewOutlineProvider() { @@ -124,9 +129,6 @@ public class TaskViewHeader extends FrameLayout { mActivityDescription = (TextView) findViewById(R.id.activity_description); mDismissButton = (ImageView) findViewById(R.id.dismiss_task); mMoveTaskButton = (ImageView) findViewById(R.id.move_task); - if (mConfig.multiStackEnabled) { - mMoveTaskButton.setVisibility(View.VISIBLE); - } // Hide the backgrounds if they are ripple drawables if (!Constants.DebugFlags.App.EnableTaskFiltering) { @@ -209,6 +211,32 @@ public class TaskViewHeader extends FrameLayout { mLightDismissDrawable : mDarkDismissDrawable); mDismissButton.setContentDescription(String.format(mDismissContentDescription, t.activityLabel)); + mMoveTaskButton.setVisibility((mConfig.multiStackEnabled) ? View.VISIBLE : View.INVISIBLE); + } + + /** Updates the resize task bar button. */ + void updateResizeTaskBarIcon(Task t) { + Rect display = mSsp.getWindowRect(); + Rect taskRect = mSsp.getTaskBounds(t.key.stackId); + int resId = R.drawable.star; + if (display.equals(taskRect)) { + resId = R.drawable.vector_drawable_place_fullscreen; + } else { + boolean top = display.top == taskRect.top; + boolean bottom = display.bottom == taskRect.bottom; + boolean left = display.left == taskRect.left; + boolean right = display.right == taskRect.right; + if (top && bottom && left) { + resId = R.drawable.vector_drawable_place_left; + } else if (top && bottom && right) { + resId = R.drawable.vector_drawable_place_right; + } else if (top && left && right) { + resId = R.drawable.vector_drawable_place_top; + } else if (bottom && left && right) { + resId = R.drawable.vector_drawable_place_bottom; + } + } + mMoveTaskButton.setImageResource(resId); } /** Unbinds the bar view from the task */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java index bba7682..a55e026 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java @@ -132,6 +132,8 @@ public class TaskViewTransform { /** Reset the transform on a view. */ public static void reset(View v) { + // Cancel any running animations + v.animate().cancel(); v.setTranslationX(0f); v.setTranslationY(0f); v.setTranslationZ(0f); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 0c21b20..a247c8e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -336,7 +336,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL } public void launchCamera() { - mFlashlightController.killFlashlight(); Intent intent = getCameraIntent(); boolean wouldLaunchResolverActivity = PreviewInflater.wouldLaunchResolverActivity( mContext, intent, mLockPatternUtils.getCurrentUser()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java index c9ba8f6..cd1914c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java @@ -17,20 +17,14 @@ package com.android.systemui.statusbar.policy; import android.content.Context; -import android.graphics.SurfaceTexture; import android.hardware.camera2.CameraAccessException; -import android.hardware.camera2.CameraCaptureSession; import android.hardware.camera2.CameraCharacteristics; -import android.hardware.camera2.CameraDevice; import android.hardware.camera2.CameraManager; -import android.hardware.camera2.CameraMetadata; -import android.hardware.camera2.CaptureRequest; import android.os.Handler; import android.os.HandlerThread; import android.os.Process; +import android.text.TextUtils; import android.util.Log; -import android.util.Size; -import android.view.Surface; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -44,7 +38,7 @@ public class FlashlightController { private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final int DISPATCH_ERROR = 0; - private static final int DISPATCH_OFF = 1; + private static final int DISPATCH_CHANGED = 1; private static final int DISPATCH_AVAILABILITY_CHANGED = 2; private final CameraManager mCameraManager; @@ -57,52 +51,50 @@ public class FlashlightController { /** Lock on {@code this} when accessing */ private boolean mFlashlightEnabled; - private String mCameraId; - private boolean mCameraAvailable; - private CameraDevice mCameraDevice; - private CaptureRequest mFlashlightRequest; - private CameraCaptureSession mSession; - private SurfaceTexture mSurfaceTexture; - private Surface mSurface; + private final String mCameraId; + private boolean mTorchAvailable; public FlashlightController(Context mContext) { mCameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE); - initialize(); - } - public void initialize() { + String cameraId = null; try { - mCameraId = getCameraId(); + cameraId = getCameraId(); } catch (Throwable e) { Log.e(TAG, "Couldn't initialize.", e); return; + } finally { + mCameraId = cameraId; } if (mCameraId != null) { ensureHandler(); - mCameraManager.registerAvailabilityCallback(mAvailabilityCallback, mHandler); + mCameraManager.registerTorchCallback(mTorchCallback, mHandler); } } - public synchronized void setFlashlight(boolean enabled) { - if (mFlashlightEnabled != enabled) { - mFlashlightEnabled = enabled; - postUpdateFlashlight(); - } - } - - public void killFlashlight() { - boolean enabled; + public void setFlashlight(boolean enabled) { + boolean pendingError = false; synchronized (this) { - enabled = mFlashlightEnabled; + if (mFlashlightEnabled != enabled) { + mFlashlightEnabled = enabled; + try { + mCameraManager.setTorchMode(mCameraId, enabled); + } catch (CameraAccessException e) { + Log.e(TAG, "Couldn't set torch mode", e); + mFlashlightEnabled = false; + pendingError = true; + } + } } - if (enabled) { - mHandler.post(mKillFlashlightRunnable); + dispatchModeChanged(mFlashlightEnabled); + if (pendingError) { + dispatchError(); } } public synchronized boolean isAvailable() { - return mCameraAvailable; + return mTorchAvailable; } public void addListener(FlashlightListener l) { @@ -126,42 +118,6 @@ public class FlashlightController { } } - private void startDevice() throws CameraAccessException { - mCameraManager.openCamera(getCameraId(), mCameraListener, mHandler); - } - - private void startSession() throws CameraAccessException { - mSurfaceTexture = new SurfaceTexture(false); - Size size = getSmallestSize(mCameraDevice.getId()); - mSurfaceTexture.setDefaultBufferSize(size.getWidth(), size.getHeight()); - mSurface = new Surface(mSurfaceTexture); - ArrayList<Surface> outputs = new ArrayList<>(1); - outputs.add(mSurface); - mCameraDevice.createCaptureSession(outputs, mSessionListener, mHandler); - } - - private Size getSmallestSize(String cameraId) throws CameraAccessException { - Size[] outputSizes = mCameraManager.getCameraCharacteristics(cameraId) - .get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP) - .getOutputSizes(SurfaceTexture.class); - if (outputSizes == null || outputSizes.length == 0) { - throw new IllegalStateException( - "Camera " + cameraId + "doesn't support any outputSize."); - } - Size chosen = outputSizes[0]; - for (Size s : outputSizes) { - if (chosen.getWidth() >= s.getWidth() && chosen.getHeight() >= s.getHeight()) { - chosen = s; - } - } - return chosen; - } - - private void postUpdateFlashlight() { - ensureHandler(); - mHandler.post(mUpdateFlashlightRunnable); - } - private String getCameraId() throws CameraAccessException { String[] ids = mCameraManager.getCameraIdList(); for (String id : ids) { @@ -176,70 +132,12 @@ public class FlashlightController { return null; } - private void updateFlashlight(boolean forceDisable) { - try { - boolean enabled; - synchronized (this) { - enabled = mFlashlightEnabled && !forceDisable; - } - if (enabled) { - if (mCameraDevice == null) { - startDevice(); - return; - } - if (mSession == null) { - startSession(); - return; - } - if (mFlashlightRequest == null) { - CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest( - CameraDevice.TEMPLATE_PREVIEW); - builder.set(CaptureRequest.FLASH_MODE, CameraMetadata.FLASH_MODE_TORCH); - builder.addTarget(mSurface); - CaptureRequest request = builder.build(); - mSession.capture(request, null, mHandler); - mFlashlightRequest = request; - } - } else { - if (mCameraDevice != null) { - mCameraDevice.close(); - teardown(); - } - } - - } catch (CameraAccessException|IllegalStateException|UnsupportedOperationException e) { - Log.e(TAG, "Error in updateFlashlight", e); - handleError(); - } - } - - private void teardown() { - mCameraDevice = null; - mSession = null; - mFlashlightRequest = null; - if (mSurface != null) { - mSurface.release(); - mSurfaceTexture.release(); - } - mSurface = null; - mSurfaceTexture = null; - } - - private void handleError() { - synchronized (this) { - mFlashlightEnabled = false; - } - dispatchError(); - dispatchOff(); - updateFlashlight(true /* forceDisable */); - } - - private void dispatchOff() { - dispatchListeners(DISPATCH_OFF, false /* argument (ignored) */); + private void dispatchModeChanged(boolean enabled) { + dispatchListeners(DISPATCH_CHANGED, enabled); } private void dispatchError() { - dispatchListeners(DISPATCH_ERROR, false /* argument (ignored) */); + dispatchListeners(DISPATCH_CHANGED, false /* argument (ignored) */); } private void dispatchAvailabilityChanged(boolean available) { @@ -255,8 +153,8 @@ public class FlashlightController { if (l != null) { if (message == DISPATCH_ERROR) { l.onFlashlightError(); - } else if (message == DISPATCH_OFF) { - l.onFlashlightOff(); + } else if (message == DISPATCH_CHANGED) { + l.onFlashlightChanged(argument); } else if (message == DISPATCH_AVAILABILITY_CHANGED) { l.onFlashlightAvailabilityChanged(argument); } @@ -279,106 +177,57 @@ public class FlashlightController { } } - private final CameraDevice.StateListener mCameraListener = new CameraDevice.StateListener() { - @Override - public void onOpened(CameraDevice camera) { - mCameraDevice = camera; - postUpdateFlashlight(); - } - - @Override - public void onDisconnected(CameraDevice camera) { - if (mCameraDevice == camera) { - dispatchOff(); - teardown(); - } - } - - @Override - public void onError(CameraDevice camera, int error) { - Log.e(TAG, "Camera error: camera=" + camera + " error=" + error); - if (camera == mCameraDevice || mCameraDevice == null) { - handleError(); - } - } - }; + private final CameraManager.TorchCallback mTorchCallback = + new CameraManager.TorchCallback() { - private final CameraCaptureSession.StateListener mSessionListener = - new CameraCaptureSession.StateListener() { @Override - public void onConfigured(CameraCaptureSession session) { - if (session.getDevice() == mCameraDevice) { - mSession = session; - } else { - session.close(); - } - postUpdateFlashlight(); - } - - @Override - public void onConfigureFailed(CameraCaptureSession session) { - Log.e(TAG, "Configure failed."); - if (mSession == null || mSession == session) { - handleError(); - } - } - }; - - private final Runnable mUpdateFlashlightRunnable = new Runnable() { - @Override - public void run() { - updateFlashlight(false /* forceDisable */); - } - }; - - private final Runnable mKillFlashlightRunnable = new Runnable() { - @Override - public void run() { - synchronized (this) { - mFlashlightEnabled = false; + public void onTorchModeUnavailable(String cameraId) { + if (TextUtils.equals(cameraId, mCameraId)) { + setCameraAvailable(false); } - updateFlashlight(true /* forceDisable */); - dispatchOff(); } - }; - private final CameraManager.AvailabilityCallback mAvailabilityCallback = - new CameraManager.AvailabilityCallback() { @Override - public void onCameraAvailable(String cameraId) { - if (DEBUG) Log.d(TAG, "onCameraAvailable(" + cameraId + ")"); - if (cameraId.equals(mCameraId)) { + public void onTorchModeChanged(String cameraId, boolean enabled) { + if (TextUtils.equals(cameraId, mCameraId)) { setCameraAvailable(true); - } - } - - @Override - public void onCameraUnavailable(String cameraId) { - if (DEBUG) Log.d(TAG, "onCameraUnavailable(" + cameraId + ")"); - if (cameraId.equals(mCameraId)) { - setCameraAvailable(false); + setTorchMode(enabled); } } private void setCameraAvailable(boolean available) { boolean changed; synchronized (FlashlightController.this) { - changed = mCameraAvailable != available; - mCameraAvailable = available; + changed = mTorchAvailable != available; + mTorchAvailable = available; } if (changed) { if (DEBUG) Log.d(TAG, "dispatchAvailabilityChanged(" + available + ")"); dispatchAvailabilityChanged(available); } } + + private void setTorchMode(boolean enabled) { + boolean changed; + synchronized (FlashlightController.this) { + changed = mFlashlightEnabled != enabled; + mFlashlightEnabled = enabled; + } + if (changed) { + if (DEBUG) Log.d(TAG, "dispatchModeChanged(" + enabled + ")"); + dispatchModeChanged(enabled); + } + } }; public interface FlashlightListener { /** - * Called when the flashlight turns off unexpectedly. + * Called when the flashlight was turned off or on. + * @param enabled true if the flashlight is currently turned on. */ - void onFlashlightOff(); + void onFlashlightChanged(boolean enabled); + /** * Called when there is an error that turns the flashlight off. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java index 2fbb812..f0dd943 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java @@ -190,7 +190,8 @@ public class SecurityControllerImpl implements SecurityController { NetworkCapabilities networkCapabilities = mConnectivityManager.getNetworkCapabilities(network); if (DEBUG) Log.d(TAG, "onAvailable " + network.netId + " : " + networkCapabilities); - if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) { + if (networkCapabilities != null && + networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) { setCurrentNetid(network.netId); } }; |