summaryrefslogtreecommitdiffstats
path: root/packages/SystemUI/src/com/android/systemui
diff options
context:
space:
mode:
Diffstat (limited to 'packages/SystemUI/src/com/android/systemui')
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/FlashlightTile.java39
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/Recents.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsResizeTaskDialog.java159
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java47
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/FlashlightController.java263
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java3
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);
}
};