Merge "ShortcutManager: implement backup & restore" into nyc-dev
diff --git a/api/current.txt b/api/current.txt
index 67f4c1f..07a4f6d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -71,6 +71,7 @@
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
+ field public static final java.lang.String GET_PASSWORD_PRIVILEGED = "android.permission.GET_PASSWORD_PRIVILEGED";
field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
@@ -19811,7 +19812,7 @@
public static abstract class AudioManager.AudioRecordingCallback {
ctor public AudioManager.AudioRecordingCallback();
- method public void onRecordConfigChanged(android.media.AudioRecordingConfiguration[]);
+ method public void onRecordingConfigChanged(android.media.AudioRecordingConfiguration[]);
}
public static abstract interface AudioManager.OnAudioFocusChangeListener {
diff --git a/api/system-current.txt b/api/system-current.txt
index 3ccd7e0..e1e73e9 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -103,6 +103,7 @@
field public static final java.lang.String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS";
field public static final java.lang.String GET_PACKAGE_IMPORTANCE = "android.permission.GET_PACKAGE_IMPORTANCE";
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
+ field public static final java.lang.String GET_PASSWORD_PRIVILEGED = "android.permission.GET_PASSWORD_PRIVILEGED";
field public static final java.lang.String GET_PROCESS_STATE_AND_OOM_SCORE = "android.permission.GET_PROCESS_STATE_AND_OOM_SCORE";
field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO";
@@ -15270,7 +15271,6 @@
ctor public ContextHubInfo();
method public int describeContents();
method public int getId();
- method public int getMaxPacketLengthBytes();
method public android.hardware.location.MemoryRegion[] getMemoryRegions();
method public java.lang.String getName();
method public float getPeakMips();
@@ -15298,6 +15298,10 @@
method public int sendMessage(int, int, android.hardware.location.ContextHubMessage);
method public int unloadNanoApp(int);
method public int unregisterCallback(android.hardware.location.ContextHubManager.Callback);
+ field public static final int ANY_HUB = -1; // 0xffffffff
+ field public static final int MSG_DATA_SEND = 3; // 0x3
+ field public static final int MSG_LOAD_NANO_APP = 1; // 0x1
+ field public static final int MSG_UNLOAD_NANO_APP = 2; // 0x2
}
public static abstract class ContextHubManager.Callback {
@@ -15491,7 +15495,7 @@
public class NanoAppInstanceInfo {
ctor public NanoAppInstanceInfo();
method public int describeContents();
- method public long getAppId();
+ method public int getAppId();
method public int getAppVersion();
method public int getContexthubId();
method public int getHandle();
@@ -15502,6 +15506,17 @@
method public int getNeededWriteMemBytes();
method public int[] getOutputEvents();
method public java.lang.String getPublisher();
+ method public void setAppId(int);
+ method public void setAppVersion(int);
+ method public void setContexthubId(int);
+ method public void setHandle(int);
+ method public void setName(java.lang.String);
+ method public void setNeededExecMemBytes(int);
+ method public void setNeededReadMemBytes(int);
+ method public void setNeededSensors(int[]);
+ method public void setNeededWriteMemBytes(int);
+ method public void setOutputEvents(int[]);
+ method public void setPublisher(java.lang.String);
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.hardware.location.NanoAppInstanceInfo> CREATOR;
}
@@ -21287,7 +21302,7 @@
public static abstract class AudioManager.AudioRecordingCallback {
ctor public AudioManager.AudioRecordingCallback();
- method public void onRecordConfigChanged(android.media.AudioRecordingConfiguration[]);
+ method public void onRecordingConfigChanged(android.media.AudioRecordingConfiguration[]);
}
public static abstract interface AudioManager.OnAudioFocusChangeListener {
diff --git a/api/test-current.txt b/api/test-current.txt
index 3be562d..09c55b9 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -71,6 +71,7 @@
field public static final java.lang.String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
field public static final java.lang.String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
+ field public static final java.lang.String GET_PASSWORD_PRIVILEGED = "android.permission.GET_PASSWORD_PRIVILEGED";
field public static final deprecated java.lang.String GET_TASKS = "android.permission.GET_TASKS";
field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
@@ -19876,7 +19877,7 @@
public static abstract class AudioManager.AudioRecordingCallback {
ctor public AudioManager.AudioRecordingCallback();
- method public void onRecordConfigChanged(android.media.AudioRecordingConfiguration[]);
+ method public void onRecordingConfigChanged(android.media.AudioRecordingConfiguration[]);
}
public static abstract interface AudioManager.OnAudioFocusChangeListener {
diff --git a/core/java/android/accounts/AccountManager.java b/core/java/android/accounts/AccountManager.java
index e520b40..7465ed9 100644
--- a/core/java/android/accounts/AccountManager.java
+++ b/core/java/android/accounts/AccountManager.java
@@ -2798,6 +2798,15 @@
if (account == null) {
throw new IllegalArgumentException("account is null");
}
+
+ // Always include the calling package name. This just makes life easier
+ // down stream.
+ final Bundle optionsIn = new Bundle();
+ if (options != null) {
+ optionsIn.putAll(options);
+ }
+ optionsIn.putString(KEY_ANDROID_PACKAGE_NAME, mContext.getPackageName());
+
return new AmsTask(activity, handler, callback) {
@Override
public void doWork() throws RemoteException {
@@ -2806,7 +2815,7 @@
account,
authTokenType,
activity != null,
- options);
+ optionsIn);
}
}.start();
}
diff --git a/core/java/android/app/ActivityTransitionState.java b/core/java/android/app/ActivityTransitionState.java
index d3ca7ee..4a1aff7 100644
--- a/core/java/android/app/ActivityTransitionState.java
+++ b/core/java/android/app/ActivityTransitionState.java
@@ -239,9 +239,6 @@
public void onResume(Activity activity, boolean isTopOfTask) {
// After orientation change, the onResume can come in before the top Activity has
// left, so if the Activity is not top, wait a second for the top Activity to exit.
- if (mCalledExitCoordinator == null) {
- return; // This is the called activity
- }
if (isTopOfTask || mEnterTransitionCoordinator == null) {
restoreExitedViews();
restoreReenteringViews();
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index cb2130c..e4fff9d 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -905,10 +905,12 @@
ListenerWrapper wrapper = null;
synchronized (AlarmManager.class) {
- final WeakReference<ListenerWrapper> wrapperRef;
- wrapperRef = sWrappers.get(listener);
- if (wrapperRef != null) {
- wrapper = wrapperRef.get();
+ if (sWrappers != null) {
+ final WeakReference<ListenerWrapper> wrapperRef;
+ wrapperRef = sWrappers.get(listener);
+ if (wrapperRef != null) {
+ wrapper = wrapperRef.get();
+ }
}
}
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 54e2989..85a0403 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -16,6 +16,10 @@
package android.app;
+import com.android.internal.R;
+import com.android.internal.app.WindowDecorActionBar;
+import com.android.internal.policy.PhoneWindow;
+
import android.annotation.CallSuper;
import android.annotation.DrawableRes;
import android.annotation.IdRes;
@@ -56,12 +60,7 @@
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
-import com.android.internal.R;
-import com.android.internal.app.WindowDecorActionBar;
-import com.android.internal.policy.PhoneWindow;
-
import java.lang.ref.WeakReference;
-import java.util.List;
/**
* Base class for Dialogs.
@@ -93,11 +92,14 @@
KeyEvent.Callback, OnCreateContextMenuListener, Window.OnWindowDismissedCallback {
private static final String TAG = "Dialog";
private Activity mOwnerActivity;
-
+
+ private final WindowManager mWindowManager;
+
final Context mContext;
- final WindowManager mWindowManager;
- Window mWindow;
+ final Window mWindow;
+
View mDecor;
+
private ActionBar mActionBar;
/**
* This field should be made private, so it is hidden from the SDK.
@@ -122,7 +124,7 @@
private static final int CANCEL = 0x44;
private static final int SHOW = 0x45;
- private Handler mListenersHandler;
+ private final Handler mListenersHandler;
private SearchEvent mSearchEvent;
@@ -130,11 +132,7 @@
private int mActionModeTypeStarting = ActionMode.TYPE_PRIMARY;
- private final Runnable mDismissAction = new Runnable() {
- public void run() {
- dismissDialog();
- }
- };
+ private final Runnable mDismissAction = this::dismissDialog;
/**
* Creates a dialog window that uses the default dialog theme.
@@ -197,14 +195,15 @@
* @hide
*/
@Deprecated
- protected Dialog(@NonNull Context context, boolean cancelable, Message cancelCallback) {
+ protected Dialog(@NonNull Context context, boolean cancelable,
+ @Nullable Message cancelCallback) {
this(context);
mCancelable = cancelable;
mCancelMessage = cancelCallback;
}
protected Dialog(@NonNull Context context, boolean cancelable,
- OnCancelListener cancelListener) {
+ @Nullable OnCancelListener cancelListener) {
this(context);
mCancelable = cancelable;
setOnCancelListener(cancelListener);
@@ -215,8 +214,7 @@
*
* @return Context The Context used by the Dialog.
*/
- @NonNull
- public final Context getContext() {
+ public final @NonNull Context getContext() {
return mContext;
}
@@ -225,7 +223,7 @@
*
* @return The ActionBar attached to the dialog or null if no ActionBar is present.
*/
- public ActionBar getActionBar() {
+ public @Nullable ActionBar getActionBar() {
return mActionBar;
}
@@ -235,7 +233,7 @@
*
* @param activity The Activity that owns this dialog.
*/
- public final void setOwnerActivity(Activity activity) {
+ public final void setOwnerActivity(@NonNull Activity activity) {
mOwnerActivity = activity;
getWindow().setVolumeControlStream(mOwnerActivity.getVolumeControlStream());
@@ -249,7 +247,7 @@
*
* @return The Activity that owns this Dialog.
*/
- public final Activity getOwnerActivity() {
+ public final @Nullable Activity getOwnerActivity() {
return mOwnerActivity;
}
@@ -315,13 +313,10 @@
l = nl;
}
- try {
- mWindowManager.addView(mDecor, l);
- mShowing = true;
-
- sendShowMessage();
- } finally {
- }
+ mWindowManager.addView(mDecor, l);
+ mShowing = true;
+
+ sendShowMessage();
}
/**
@@ -387,7 +382,7 @@
}
}
- // internal method to make sure mcreated is set properly without requiring
+ // internal method to make sure mCreated is set properly without requiring
// users to call through to super in onCreate
void dispatchOnCreate(Bundle savedInstanceState) {
if (!mCreated) {
@@ -399,7 +394,7 @@
/**
* Similar to {@link Activity#onCreate}, you should initialize your dialog
* in this method, including calling {@link #setContentView}.
- * @param savedInstanceState If this dialog is being reinitalized after a
+ * @param savedInstanceState If this dialog is being reinitialized after a
* the hosting activity was previously shut down, holds the result from
* the most recent call to {@link #onSaveInstanceState}, or null if this
* is the first time.
@@ -432,7 +427,7 @@
* state.
* @return A bundle with the state of the dialog.
*/
- public Bundle onSaveInstanceState() {
+ public @NonNull Bundle onSaveInstanceState() {
Bundle bundle = new Bundle();
bundle.putBoolean(DIALOG_SHOWING_TAG, mShowing);
if (mCreated) {
@@ -451,7 +446,7 @@
* @param savedInstanceState The state of the dialog previously saved by
* {@link #onSaveInstanceState()}.
*/
- public void onRestoreInstanceState(Bundle savedInstanceState) {
+ public void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
final Bundle dialogHierarchyState = savedInstanceState.getBundle(DIALOG_HIERARCHY_TAG);
if (dialogHierarchyState == null) {
// dialog has never been shown, or onCreated, nothing to restore.
@@ -472,7 +467,7 @@
* @return Window The current window, or null if the activity is not
* visual.
*/
- public Window getWindow() {
+ public @Nullable Window getWindow() {
return mWindow;
}
@@ -485,7 +480,7 @@
* @see #getWindow
* @see android.view.Window#getCurrentFocus
*/
- public View getCurrentFocus() {
+ public @Nullable View getCurrentFocus() {
return mWindow != null ? mWindow.getCurrentFocus() : null;
}
@@ -497,8 +492,7 @@
* @param id the identifier of the view to find
* @return The view with the given id or null.
*/
- @Nullable
- public View findViewById(@IdRes int id) {
+ public @Nullable View findViewById(@IdRes int id) {
return mWindow.findViewById(id);
}
@@ -519,19 +513,19 @@
*
* @param view The desired content to display.
*/
- public void setContentView(View view) {
+ public void setContentView(@NonNull View view) {
mWindow.setContentView(view);
}
/**
* Set the screen content to an explicit view. This view is placed
* directly into the screen's view hierarchy. It can itself be a complex
- * view hierarhcy.
+ * view hierarchy.
*
* @param view The desired content to display.
* @param params Layout parameters for the view.
*/
- public void setContentView(View view, ViewGroup.LayoutParams params) {
+ public void setContentView(@NonNull View view, @Nullable ViewGroup.LayoutParams params) {
mWindow.setContentView(view, params);
}
@@ -542,7 +536,7 @@
* @param view The desired content to display.
* @param params Layout parameters for the view.
*/
- public void addContentView(View view, ViewGroup.LayoutParams params) {
+ public void addContentView(@NonNull View view, @Nullable ViewGroup.LayoutParams params) {
mWindow.addContentView(view, params);
}
@@ -551,7 +545,7 @@
*
* @param title The new text to display in the title.
*/
- public void setTitle(CharSequence title) {
+ public void setTitle(@Nullable CharSequence title) {
mWindow.setTitle(title);
mWindow.getAttributes().setTitle(title);
}
@@ -577,7 +571,8 @@
* @see #onKeyUp
* @see android.view.KeyEvent
*/
- public boolean onKeyDown(int keyCode, KeyEvent event) {
+ @Override
+ public boolean onKeyDown(int keyCode, @NonNull KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
event.startTracking();
return true;
@@ -591,7 +586,8 @@
* KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle
* the event).
*/
- public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+ @Override
+ public boolean onKeyLongPress(int keyCode, @NonNull KeyEvent event) {
return false;
}
@@ -604,7 +600,8 @@
* @see #onKeyDown
* @see KeyEvent
*/
- public boolean onKeyUp(int keyCode, KeyEvent event) {
+ @Override
+ public boolean onKeyUp(int keyCode, @NonNull KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.isTracking()
&& !event.isCanceled()) {
onBackPressed();
@@ -618,7 +615,8 @@
* KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle
* the event).
*/
- public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
+ @Override
+ public boolean onKeyMultiple(int keyCode, int repeatCount, @NonNull KeyEvent event) {
return false;
}
@@ -643,7 +641,7 @@
* @param event Description of the key event.
* @return True if the key shortcut was handled.
*/
- public boolean onKeyShortcut(int keyCode, KeyEvent event) {
+ public boolean onKeyShortcut(int keyCode, @NonNull KeyEvent event) {
return false;
}
@@ -657,7 +655,7 @@
* The default implementation will cancel the dialog when a touch
* happens outside of the window bounds.
*/
- public boolean onTouchEvent(MotionEvent event) {
+ public boolean onTouchEvent(@NonNull MotionEvent event) {
if (mCancelable && mShowing && mWindow.shouldCloseOnTouch(mContext, event)) {
cancel();
return true;
@@ -680,7 +678,7 @@
* @return Return true if you have consumed the event, false if you haven't.
* The default implementation always returns false.
*/
- public boolean onTrackballEvent(MotionEvent event) {
+ public boolean onTrackballEvent(@NonNull MotionEvent event) {
return false;
}
@@ -709,25 +707,30 @@
* @return Return true if you have consumed the event, false if you haven't.
* The default implementation always returns false.
*/
- public boolean onGenericMotionEvent(MotionEvent event) {
+ public boolean onGenericMotionEvent(@NonNull MotionEvent event) {
return false;
}
+ @Override
public void onWindowAttributesChanged(WindowManager.LayoutParams params) {
if (mDecor != null) {
mWindowManager.updateViewLayout(mDecor, params);
}
}
+ @Override
public void onContentChanged() {
}
+ @Override
public void onWindowFocusChanged(boolean hasFocus) {
}
+ @Override
public void onAttachedToWindow() {
}
+ @Override
public void onDetachedFromWindow() {
}
@@ -746,7 +749,8 @@
*
* @return boolean Return true if this event was consumed.
*/
- public boolean dispatchKeyEvent(KeyEvent event) {
+ @Override
+ public boolean dispatchKeyEvent(@NonNull KeyEvent event) {
if ((mOnKeyListener != null) && (mOnKeyListener.onKey(this, event.getKeyCode(), event))) {
return true;
}
@@ -766,7 +770,8 @@
* @param event The key shortcut event.
* @return True if this event was consumed.
*/
- public boolean dispatchKeyShortcutEvent(KeyEvent event) {
+ @Override
+ public boolean dispatchKeyShortcutEvent(@NonNull KeyEvent event) {
if (mWindow.superDispatchKeyShortcutEvent(event)) {
return true;
}
@@ -783,7 +788,8 @@
*
* @return boolean Return true if this event was consumed.
*/
- public boolean dispatchTouchEvent(MotionEvent ev) {
+ @Override
+ public boolean dispatchTouchEvent(@NonNull MotionEvent ev) {
if (mWindow.superDispatchTouchEvent(ev)) {
return true;
}
@@ -800,7 +806,8 @@
*
* @return boolean Return true if this event was consumed.
*/
- public boolean dispatchTrackballEvent(MotionEvent ev) {
+ @Override
+ public boolean dispatchTrackballEvent(@NonNull MotionEvent ev) {
if (mWindow.superDispatchTrackballEvent(ev)) {
return true;
}
@@ -817,14 +824,16 @@
*
* @return boolean Return true if this event was consumed.
*/
- public boolean dispatchGenericMotionEvent(MotionEvent ev) {
+ @Override
+ public boolean dispatchGenericMotionEvent(@NonNull MotionEvent ev) {
if (mWindow.superDispatchGenericMotionEvent(ev)) {
return true;
}
return onGenericMotionEvent(ev);
}
- public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+ @Override
+ public boolean dispatchPopulateAccessibilityEvent(@NonNull AccessibilityEvent event) {
event.setClassName(getClass().getName());
event.setPackageName(mContext.getPackageName());
@@ -839,6 +848,7 @@
/**
* @see Activity#onCreatePanelView(int)
*/
+ @Override
public View onCreatePanelView(int featureId) {
return null;
}
@@ -846,7 +856,8 @@
/**
* @see Activity#onCreatePanelMenu(int, Menu)
*/
- public boolean onCreatePanelMenu(int featureId, Menu menu) {
+ @Override
+ public boolean onCreatePanelMenu(int featureId, @NonNull Menu menu) {
if (featureId == Window.FEATURE_OPTIONS_PANEL) {
return onCreateOptionsMenu(menu);
}
@@ -857,10 +868,10 @@
/**
* @see Activity#onPreparePanel(int, View, Menu)
*/
+ @Override
public boolean onPreparePanel(int featureId, View view, Menu menu) {
if (featureId == Window.FEATURE_OPTIONS_PANEL && menu != null) {
- boolean goforit = onPrepareOptionsMenu(menu);
- return goforit && menu.hasVisibleItems();
+ return onPrepareOptionsMenu(menu) && menu.hasVisibleItems();
}
return true;
}
@@ -868,6 +879,7 @@
/**
* @see Activity#onMenuOpened(int, Menu)
*/
+ @Override
public boolean onMenuOpened(int featureId, Menu menu) {
if (featureId == Window.FEATURE_ACTION_BAR) {
mActionBar.dispatchMenuVisibilityChanged(true);
@@ -878,6 +890,7 @@
/**
* @see Activity#onMenuItemSelected(int, MenuItem)
*/
+ @Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
return false;
}
@@ -885,6 +898,7 @@
/**
* @see Activity#onPanelClosed(int, Menu)
*/
+ @Override
public void onPanelClosed(int featureId, Menu menu) {
if (featureId == Window.FEATURE_ACTION_BAR) {
mActionBar.dispatchMenuVisibilityChanged(false);
@@ -899,7 +913,7 @@
* @see Activity#onCreateOptionsMenu(Menu)
* @see #getOwnerActivity()
*/
- public boolean onCreateOptionsMenu(Menu menu) {
+ public boolean onCreateOptionsMenu(@NonNull Menu menu) {
return true;
}
@@ -911,21 +925,21 @@
* @see Activity#onPrepareOptionsMenu(Menu)
* @see #getOwnerActivity()
*/
- public boolean onPrepareOptionsMenu(Menu menu) {
+ public boolean onPrepareOptionsMenu(@NonNull Menu menu) {
return true;
}
/**
* @see Activity#onOptionsItemSelected(MenuItem)
*/
- public boolean onOptionsItemSelected(MenuItem item) {
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
return false;
}
/**
* @see Activity#onOptionsMenuClosed(Menu)
*/
- public void onOptionsMenuClosed(Menu menu) {
+ public void onOptionsMenuClosed(@NonNull Menu menu) {
}
/**
@@ -958,47 +972,49 @@
/**
* @see Activity#onCreateContextMenu(ContextMenu, View, ContextMenuInfo)
*/
+ @Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
}
/**
* @see Activity#registerForContextMenu(View)
*/
- public void registerForContextMenu(View view) {
+ public void registerForContextMenu(@NonNull View view) {
view.setOnCreateContextMenuListener(this);
}
/**
* @see Activity#unregisterForContextMenu(View)
*/
- public void unregisterForContextMenu(View view) {
+ public void unregisterForContextMenu(@NonNull View view) {
view.setOnCreateContextMenuListener(null);
}
/**
* @see Activity#openContextMenu(View)
*/
- public void openContextMenu(View view) {
+ public void openContextMenu(@NonNull View view) {
view.showContextMenu();
}
/**
* @see Activity#onContextItemSelected(MenuItem)
*/
- public boolean onContextItemSelected(MenuItem item) {
+ public boolean onContextItemSelected(@NonNull MenuItem item) {
return false;
}
/**
* @see Activity#onContextMenuClosed(Menu)
*/
- public void onContextMenuClosed(Menu menu) {
+ public void onContextMenuClosed(@NonNull Menu menu) {
}
/**
* This hook is called when the user signals the desire to start a search.
*/
- public boolean onSearchRequested(SearchEvent searchEvent) {
+ @Override
+ public boolean onSearchRequested(@NonNull SearchEvent searchEvent) {
mSearchEvent = searchEvent;
return onSearchRequested();
}
@@ -1006,6 +1022,7 @@
/**
* This hook is called when the user signals the desire to start a search.
*/
+ @Override
public boolean onSearchRequested() {
final SearchManager searchManager = (SearchManager) mContext
.getSystemService(Context.SEARCH_SERVICE);
@@ -1028,13 +1045,10 @@
* @return SearchEvent The SearchEvent that triggered the {@link
* #onSearchRequested} callback.
*/
- public final SearchEvent getSearchEvent() {
+ public final @Nullable SearchEvent getSearchEvent() {
return mSearchEvent;
}
- /**
- * {@inheritDoc}
- */
@Override
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback) {
if (mActionBar != null && mActionModeTypeStarting == ActionMode.TYPE_PRIMARY) {
@@ -1043,9 +1057,6 @@
return null;
}
- /**
- * {@inheritDoc}
- */
@Override
public ActionMode onWindowStartingActionMode(ActionMode.Callback callback, int type) {
try {
@@ -1062,6 +1073,7 @@
* Note that if you override this method you should always call through
* to the superclass implementation by calling super.onActionModeStarted(mode).
*/
+ @Override
@CallSuper
public void onActionModeStarted(ActionMode mode) {
mActionMode = mode;
@@ -1073,6 +1085,7 @@
* Note that if you override this method you should always call through
* to the superclass implementation by calling super.onActionModeFinished(mode).
*/
+ @Override
@CallSuper
public void onActionModeFinished(ActionMode mode) {
if (mode == mActionMode) {
@@ -1138,7 +1151,7 @@
* Convenience for calling
* {@link android.view.Window#setFeatureDrawableUri}.
*/
- public final void setFeatureDrawableUri(int featureId, Uri uri) {
+ public final void setFeatureDrawableUri(int featureId, @Nullable Uri uri) {
getWindow().setFeatureDrawableUri(featureId, uri);
}
@@ -1146,7 +1159,7 @@
* Convenience for calling
* {@link android.view.Window#setFeatureDrawable(int, Drawable)}.
*/
- public final void setFeatureDrawable(int featureId, Drawable drawable) {
+ public final void setFeatureDrawable(int featureId, @Nullable Drawable drawable) {
getWindow().setFeatureDrawable(featureId, drawable);
}
@@ -1158,7 +1171,7 @@
getWindow().setFeatureDrawableAlpha(featureId, alpha);
}
- public LayoutInflater getLayoutInflater() {
+ public @NonNull LayoutInflater getLayoutInflater() {
return getWindow().getLayoutInflater();
}
@@ -1190,6 +1203,7 @@
* Cancel the dialog. This is essentially the same as calling {@link #dismiss()}, but it will
* also call your {@link DialogInterface.OnCancelListener} (if registered).
*/
+ @Override
public void cancel() {
if (!mCanceled && mCancelMessage != null) {
mCanceled = true;
@@ -1210,7 +1224,7 @@
*
* @param listener The {@link DialogInterface.OnCancelListener} to use.
*/
- public void setOnCancelListener(final OnCancelListener listener) {
+ public void setOnCancelListener(@Nullable OnCancelListener listener) {
if (mCancelAndDismissTaken != null) {
throw new IllegalStateException(
"OnCancelListener is already taken by "
@@ -1228,7 +1242,7 @@
* @param msg The msg to send when the dialog is canceled.
* @see #setOnCancelListener(android.content.DialogInterface.OnCancelListener)
*/
- public void setCancelMessage(final Message msg) {
+ public void setCancelMessage(@Nullable Message msg) {
mCancelMessage = msg;
}
@@ -1236,7 +1250,7 @@
* Set a listener to be invoked when the dialog is dismissed.
* @param listener The {@link DialogInterface.OnDismissListener} to use.
*/
- public void setOnDismissListener(final OnDismissListener listener) {
+ public void setOnDismissListener(@Nullable OnDismissListener listener) {
if (mCancelAndDismissTaken != null) {
throw new IllegalStateException(
"OnDismissListener is already taken by "
@@ -1253,7 +1267,7 @@
* Sets a listener to be invoked when the dialog is shown.
* @param listener The {@link DialogInterface.OnShowListener} to use.
*/
- public void setOnShowListener(OnShowListener listener) {
+ public void setOnShowListener(@Nullable OnShowListener listener) {
if (listener != null) {
mShowMessage = mListenersHandler.obtainMessage(SHOW, listener);
} else {
@@ -1265,13 +1279,13 @@
* Set a message to be sent when the dialog is dismissed.
* @param msg The msg to send when the dialog is dismissed.
*/
- public void setDismissMessage(final Message msg) {
+ public void setDismissMessage(@Nullable Message msg) {
mDismissMessage = msg;
}
/** @hide */
- public boolean takeCancelAndDismissListeners(String msg, final OnCancelListener cancel,
- final OnDismissListener dismiss) {
+ public boolean takeCancelAndDismissListeners(@Nullable String msg,
+ @Nullable OnCancelListener cancel, @Nullable OnDismissListener dismiss) {
if (mCancelAndDismissTaken != null) {
mCancelAndDismissTaken = null;
} else if (mCancelMessage != null || mDismissMessage != null) {
@@ -1305,15 +1319,15 @@
/**
* Sets the callback that will be called if a key is dispatched to the dialog.
*/
- public void setOnKeyListener(final OnKeyListener onKeyListener) {
+ public void setOnKeyListener(@Nullable OnKeyListener onKeyListener) {
mOnKeyListener = onKeyListener;
}
private static final class ListenersHandler extends Handler {
- private WeakReference<DialogInterface> mDialog;
+ private final WeakReference<DialogInterface> mDialog;
public ListenersHandler(Dialog dialog) {
- mDialog = new WeakReference<DialogInterface>(dialog);
+ mDialog = new WeakReference<>(dialog);
}
@Override
diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java
index e355a1c..35437a1 100644
--- a/core/java/android/bluetooth/BluetoothManager.java
+++ b/core/java/android/bluetooth/BluetoothManager.java
@@ -144,7 +144,7 @@
}
/**
- *
+ *
* Get a list of devices that match any of the given connection
* states.
*
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
index ae44f1d..644e29f 100644
--- a/core/java/android/hardware/location/ContextHubInfo.java
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -37,7 +37,6 @@
private float mStoppedPowerDrawMw;
private float mSleepPowerDrawMw;
private float mPeakPowerDrawMw;
- private int mMaxPacketLengthBytes;
private int[] mSupportedSensors;
@@ -47,27 +46,6 @@
}
/**
- * returns the maximum number of bytes that can be sent per message to the hub
- *
- * @return int - maximum bytes that can be transmitted in a
- * single packet
- */
- public int getMaxPacketLengthBytes() {
- return mMaxPacketLengthBytes;
- }
-
- /**
- * set the context hub unique identifer
- *
- * @param bytes - Maximum number of bytes per message
- *
- * @hide
- */
- public void setMaxPacketLenBytes(int bytes) {
- mMaxPacketLengthBytes = bytes;
- }
-
- /**
* get the context hub unique identifer
*
* @return int - unique system wide identifier
@@ -396,4 +374,4 @@
return new ContextHubInfo[size];
}
};
-}
\ No newline at end of file
+}
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index 89edaa9..4ddf767 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -43,6 +43,23 @@
private Handler mCallbackHandler;
/**
+ * A special context hub identifier meaning any possible hub on the system.
+ */
+ public static final int ANY_HUB = -1;
+ /**
+ * A constant denoting a message to load a a Nano App
+ */
+ public static final int MSG_LOAD_NANO_APP = 1;
+ /**
+ * A constant denoting a message to unload a a Nano App
+ */
+ public static final int MSG_UNLOAD_NANO_APP = 2;
+ /**
+ * A constant denoting a message to send a message
+ */
+ public static final int MSG_DATA_SEND = 3;
+
+ /**
* An interface to receive asynchronous communication from the context hub.
*/
public abstract static class Callback {
@@ -52,7 +69,7 @@
* Callback function called on message receipt from context hub.
*
* @param hubHandle Handle (system-wide unique identifier) of the hub of the message.
- * @param nanoAppHandle Handle (unique identifier) for app instance that sent the message.
+ * @param nanoAppHandle Handle (unique identifier) for the app that sent the message.
* @param message The context hub message.
*
* @see ContextHubMessage
@@ -72,7 +89,7 @@
try {
retVal = getBinder().getContextHubHandles();
} catch (RemoteException e) {
- Log.w(TAG, "Could not fetch context hub handles : " + e);
+ Log.e(TAG, "Could not fetch context hub handles : " + e);
}
return retVal;
}
@@ -90,7 +107,7 @@
try {
retVal = getBinder().getContextHubInfo(hubHandle);
} catch (RemoteException e) {
- Log.w(TAG, "Could not fetch context hub info :" + e);
+ Log.e(TAG, "Could not fetch context hub info :" + e);
}
return retVal;
@@ -109,7 +126,6 @@
*/
public int loadNanoApp(int hubHandle, NanoApp app) {
int retVal = -1;
-
if (app == null) {
return retVal;
}
@@ -117,7 +133,7 @@
try {
retVal = getBinder().loadNanoApp(hubHandle, app);
} catch (RemoteException e) {
- Log.w(TAG, "Could not load nanoApp :" + e);
+ Log.e(TAG, "Could not fetch load nanoApp :" + e);
}
return retVal;
@@ -136,7 +152,7 @@
try {
retVal = getBinder().unloadNanoApp(nanoAppHandle);
} catch (RemoteException e) {
- Log.w(TAG, "Could not fetch unload nanoApp :" + e);
+ Log.e(TAG, "Could not fetch unload nanoApp :" + e);
}
return retVal;
@@ -156,7 +172,7 @@
try {
retVal = getBinder().getNanoAppInstanceInfo(nanoAppHandle);
} catch (RemoteException e) {
- Log.w(TAG, "Could not fetch nanoApp info :" + e);
+ Log.e(TAG, "Could not fetch nanoApp info :" + e);
}
return retVal;
@@ -177,7 +193,7 @@
try {
retVal = getBinder().findNanoAppOnHub(hubHandle, filter);
} catch (RemoteException e) {
- Log.w(TAG, "Could not query nanoApp instance :" + e);
+ Log.e(TAG, "Could not query nanoApp instance :" + e);
}
return retVal;
}
@@ -196,14 +212,10 @@
public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage message) {
int retVal = -1;
- if (message == null || message.getData() == null) {
- Log.w(TAG, "null ptr");
- return retVal;
- }
try {
retVal = getBinder().sendMessage(hubHandle, nanoAppHandle, message);
} catch (RemoteException e) {
- Log.w(TAG, "Could not send message :" + e.toString());
+ Log.e(TAG, "Could not fetch send message :" + e.toString());
}
return retVal;
@@ -235,7 +247,7 @@
public int registerCallback(Callback callback, Handler handler) {
synchronized(this) {
if (mCallback != null) {
- Log.w(TAG, "Max number of callbacks reached!");
+ Log.e(TAG, "Max number of callbacks reached!");
return -1;
}
mCallback = callback;
@@ -256,7 +268,7 @@
public int unregisterCallback(Callback callback) {
synchronized(this) {
if (callback != mCallback) {
- Log.w(TAG, "Cannot recognize callback!");
+ Log.e(TAG, "Cannot recognize callback!");
return -1;
}
@@ -299,11 +311,11 @@
try {
getBinder().registerCallback(mClientCallback);
} catch (RemoteException e) {
- Log.w(TAG, "Could not register callback:" + e);
+ Log.e(TAG, "Could not register callback:" + e);
}
} else {
- Log.w(TAG, "failed to getService");
+ Log.d(TAG, "failed to getService");
}
}
diff --git a/core/java/android/hardware/location/ContextHubMessage.java b/core/java/android/hardware/location/ContextHubMessage.java
index bca2ae6..954e97d 100644
--- a/core/java/android/hardware/location/ContextHubMessage.java
+++ b/core/java/android/hardware/location/ContextHubMessage.java
@@ -16,10 +16,10 @@
package android.hardware.location;
+
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Log;
import java.util.Arrays;
@@ -32,9 +32,6 @@
private int mVersion;
private byte[]mData;
- private static final String TAG = "ContextHubMessage";
-
-
/**
* Get the message type
*
@@ -109,11 +106,9 @@
private ContextHubMessage(Parcel in) {
mType = in.readInt();
mVersion = in.readInt();
- int bufferLength = in.readInt();
- mData = new byte[bufferLength];
- in.readByteArray(mData);
+ byte[] byteBuffer = new byte[in.readInt()];
+ in.readByteArray(byteBuffer);
}
-
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mType);
out.writeInt(mVersion);
diff --git a/core/java/android/hardware/location/ContextHubService.java b/core/java/android/hardware/location/ContextHubService.java
index b65e24e..274babe 100644
--- a/core/java/android/hardware/location/ContextHubService.java
+++ b/core/java/android/hardware/location/ContextHubService.java
@@ -29,30 +29,12 @@
*/
public class ContextHubService extends IContextHubService.Stub {
- public static final String CONTEXTHUB_SERVICE = "contexthub_service";
-
private static final String TAG = "ContextHubService";
private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE;
private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '"
+ HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware";
-
- public static final int ANY_HUB = -1;
- public static final int MSG_LOAD_NANO_APP = 5;
- public static final int MSG_UNLOAD_NANO_APP = 2;
-
- private static final String PRE_LOADED_GENERIC_UNKNOWN = "Preloaded app, unknown";
- private static final String PRE_LOADED_APP_NAME = PRE_LOADED_GENERIC_UNKNOWN;
- private static final String PRE_LOADED_APP_PUBLISHER = PRE_LOADED_GENERIC_UNKNOWN;
- private static final int PRE_LOADED_APP_MEM_REQ = 0;
-
- private static final int MSG_HEADER_SIZE = 4;
- private static final int MSG_FIELD_TYPE = 0;
- private static final int MSG_FIELD_VERSION = 1;
- private static final int MSG_FIELD_HUB_HANDLE = 2;
- private static final int MSG_FIELD_APP_INSTANCE = 3;
-
- private static final int OS_APP_INSTANCE = -1;
+ public static final String CONTEXTHUB_SERVICE = "contexthub_service";
private final Context mContext;
@@ -60,27 +42,44 @@
private ContextHubInfo[] mContextHubInfo;
private IContextHubCallback mCallback;
- private native int nativeSendMessage(int[] header, byte[] data);
- private native ContextHubInfo[] nativeInitialize();
-
-
public ContextHubService(Context context) {
mContext = context;
mContextHubInfo = nativeInitialize();
- mNanoAppHash = new HashMap<Integer, NanoAppInstanceInfo>();
for (int i = 0; i < mContextHubInfo.length; i++) {
- Log.d(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
+ Log.v(TAG, "ContextHub[" + i + "] id: " + mContextHubInfo[i].getId()
+ ", name: " + mContextHubInfo[i].getName());
}
}
+ private native int nativeSendMessage(int[] header, byte[] data);
+ private native ContextHubInfo[] nativeInitialize();
+
@Override
- public int registerCallback(IContextHubCallback callback) throws RemoteException {
+ public int registerCallback(IContextHubCallback callback) throws RemoteException{
checkPermissions();
- synchronized(this) {
- mCallback = callback;
+ mCallback = callback;
+ return 0;
+ }
+
+
+ private int onMessageReceipt(int[] header, byte[] data) {
+ if (mCallback != null) {
+ // TODO : Defend against unexpected header sizes
+ // Add abstraction for magic numbers
+ // onMessageRecipt should pass the right arguments
+ ContextHubMessage msg = new ContextHubMessage(header[0], header[1], data);
+
+ try {
+ mCallback.onMessageReceipt(0, 0, msg);
+ } catch (Exception e) {
+ Log.e(TAG, "Exception " + e + " when calling remote callback");
+ return -1;
+ }
+ } else {
+ Log.d(TAG, "Message Callback is NULL");
}
+
return 0;
}
@@ -119,17 +118,14 @@
}
// Call Native interface here
- int[] msgHeader = new int[MSG_HEADER_SIZE];
- msgHeader[MSG_FIELD_HUB_HANDLE] = contextHubHandle;
- msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE;
- msgHeader[MSG_FIELD_VERSION] = 0;
- msgHeader[MSG_FIELD_TYPE] = MSG_LOAD_NANO_APP;
+ int[] msgHeader = new int[8];
+ msgHeader[0] = contextHubHandle;
+ msgHeader[1] = app.getAppId();
+ msgHeader[2] = app.getAppVersion();
+ msgHeader[3] = ContextHubManager.MSG_LOAD_NANO_APP;
+ msgHeader[4] = 0; // Loading hints
- if (nativeSendMessage(msgHeader, app.getAppBinary()) != 0) {
- return -1;
- }
- // Do not add an entry to mNanoAppInstance Hash yet. The HAL may reject the app
- return 0;
+ return nativeSendMessage(msgHeader, app.getAppBinary());
}
@Override
@@ -141,18 +137,12 @@
}
// Call Native interface here
- int[] msgHeader = new int[MSG_HEADER_SIZE];
- msgHeader[MSG_FIELD_HUB_HANDLE] = ANY_HUB;
- msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE;
- msgHeader[MSG_FIELD_VERSION] = 0;
- msgHeader[MSG_FIELD_TYPE] = MSG_UNLOAD_NANO_APP;
+ int[] msgHeader = new int[8];
+ msgHeader[0] = info.getContexthubId();
+ msgHeader[1] = ContextHubManager.MSG_UNLOAD_NANO_APP;
+ msgHeader[2] = info.getHandle();
- if(nativeSendMessage(msgHeader, null) != 0) {
- return -1;
- }
-
- // Do not add an entry to mNanoAppInstance Hash yet. The HAL may reject the app
- return 0;
+ return nativeSendMessage(msgHeader, null);
}
@Override
@@ -176,7 +166,7 @@
for(Integer nanoAppInstance : mNanoAppHash.keySet()) {
NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance);
- if (filter.testMatch(info)){
+ if(filter.testMatch(info)){
foundInstances.add(nanoAppInstance);
}
}
@@ -193,12 +183,12 @@
public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg)
throws RemoteException {
checkPermissions();
-
- int[] msgHeader = new int[MSG_HEADER_SIZE];
- msgHeader[MSG_FIELD_HUB_HANDLE] = hubHandle;
- msgHeader[MSG_FIELD_APP_INSTANCE] = nanoAppHandle;
- msgHeader[MSG_FIELD_VERSION] = msg.getVersion();
- msgHeader[MSG_FIELD_TYPE] = msg.getMsgType();
+ int[] msgHeader = new int[8];
+ msgHeader[0] = ContextHubManager.MSG_DATA_SEND;
+ msgHeader[1] = hubHandle;
+ msgHeader[2] = nanoAppHandle;
+ msgHeader[3] = msg.getMsgType();
+ msgHeader[4] = msg.getVersion();
return nativeSendMessage(msgHeader, msg.getData());
}
@@ -206,52 +196,5 @@
private void checkPermissions() {
mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE);
}
-
- private int onMessageReceipt(int[] header, byte[] data) {
- if (header == null || data == null || header.length < MSG_HEADER_SIZE) {
- return -1;
- }
-
- synchronized(this) {
- if (mCallback != null) {
- ContextHubMessage msg = new ContextHubMessage(header[MSG_FIELD_TYPE],
- header[MSG_FIELD_VERSION],
- data);
-
- try {
- mCallback.onMessageReceipt(header[MSG_FIELD_HUB_HANDLE],
- header[MSG_FIELD_APP_INSTANCE],
- msg);
- } catch (Exception e) {
- Log.w(TAG, "Exception " + e + " when calling remote callback");
- return -1;
- }
- } else {
- Log.d(TAG, "Message Callback is NULL");
- }
- }
-
- return 0;
- }
-
- private int addAppInstance(int hubHandle, int appInstanceHandle, long appId, int appVersion) {
- // App Id encodes vendor & version
- NanoAppInstanceInfo appInfo = new NanoAppInstanceInfo();
-
- appInfo.setAppId(appId);
- appInfo.setAppVersion(appVersion);
- appInfo.setName(PRE_LOADED_APP_NAME);
- appInfo.setContexthubId(hubHandle);
- appInfo.setHandle(appInstanceHandle);
- appInfo.setPublisher(PRE_LOADED_APP_PUBLISHER);
- appInfo.setNeededExecMemBytes(PRE_LOADED_APP_MEM_REQ);
- appInfo.setNeededReadMemBytes(PRE_LOADED_APP_MEM_REQ);
- appInfo.setNeededWriteMemBytes(PRE_LOADED_APP_MEM_REQ);
-
- mNanoAppHash.put(appInstanceHandle, appInfo);
- Log.d(TAG, "Added app instance " + appInstanceHandle + " with id " + appId
- + " version " + appVersion);
-
- return 0;
- }
}
+
diff --git a/core/java/android/hardware/location/NanoAppFilter.java b/core/java/android/hardware/location/NanoAppFilter.java
index 8db70e9..369f9e4 100644
--- a/core/java/android/hardware/location/NanoAppFilter.java
+++ b/core/java/android/hardware/location/NanoAppFilter.java
@@ -20,7 +20,6 @@
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
-import android.util.Log;
/**
* @hide
@@ -28,8 +27,6 @@
@SystemApi
public class NanoAppFilter {
- private static final String TAG = "NanoAppFilter";
-
// The appId, can be set to APP_ID_ANY
private long mAppId;
@@ -57,10 +54,6 @@
* If this flag is set, only versions strictly less than the version specified shall match.
*/
public static final int FLAGS_VERSION_LESS_THAN = 4;
- /**
- * If this flag is set, only versions strictly equal to the
- * version specified shall match.
- */
public static final int FLAGS_VERSION_STRICTLY_EQUAL = 8;
/**
@@ -124,9 +117,14 @@
* @return true if this is a match, false otherwise
*/
public boolean testMatch(NanoAppInstanceInfo info) {
- return (mContextHubId == HUB_ANY || info.getContexthubId() == mContextHubId) &&
+ if ((mContextHubId == HUB_ANY || info.getContexthubId() == mContextHubId) &&
(mAppId == APP_ANY || info.getAppId() == mAppId) &&
- (versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()));
+ // (mAppIdVendorMask == VENDOR_ANY) TODO : Expose Vendor mask cleanly
+ (versionsMatch(mVersionRestrictionMask, mAppVersion, info.getAppVersion()))) {
+ return true;
+ } else {
+ return false;
+ }
}
public static final Parcelable.Creator<NanoAppFilter> CREATOR
diff --git a/core/java/android/hardware/location/NanoAppInstanceInfo.java b/core/java/android/hardware/location/NanoAppInstanceInfo.java
index 977f645..ac62919 100644
--- a/core/java/android/hardware/location/NanoAppInstanceInfo.java
+++ b/core/java/android/hardware/location/NanoAppInstanceInfo.java
@@ -29,7 +29,7 @@
private String mPublisher;
private String mName;
- private long mAppId;
+ private int mAppId;
private int mAppVersion;
private int mNeededReadMemBytes;
@@ -59,8 +59,6 @@
* set the publisher name for the app
*
* @param publisher - name of the publisher
- *
- * @hide
*/
public void setPublisher(String publisher) {
mPublisher = publisher;
@@ -79,8 +77,6 @@
* set the name of the app
*
* @param name - name of the app
- *
- * @hide
*/
public void setName(String name) {
mName = name;
@@ -91,7 +87,7 @@
*
* @return int - application identifier
*/
- public long getAppId() {
+ public int getAppId() {
return mAppId;
}
@@ -99,10 +95,8 @@
* Set the application identifier
*
* @param appId - application identifier
- *
- * @hide
*/
- public void setAppId(long appId) {
+ public void setAppId(int appId) {
mAppId = appId;
}
@@ -119,8 +113,6 @@
* Set the application version
*
* @param appVersion - version of the app
- *
- * @hide
*/
public void setAppVersion(int appVersion) {
mAppVersion = appVersion;
@@ -139,8 +131,6 @@
* Set the read memory needed by the app
*
* @param neededReadMemBytes - readable Memory needed in bytes
- *
- * @hide
*/
public void setNeededReadMemBytes(int neededReadMemBytes) {
mNeededReadMemBytes = neededReadMemBytes;
@@ -160,8 +150,6 @@
*
* @param neededWriteMemBytes - writable memory needed by the
* app
- *
- * @hide
*/
public void setNeededWriteMemBytes(int neededWriteMemBytes) {
mNeededWriteMemBytes = neededWriteMemBytes;
@@ -181,8 +169,6 @@
*
* @param neededExecMemBytes - executable memory needed by the
* app
- *
- * @hide
*/
public void setNeededExecMemBytes(int neededExecMemBytes) {
mNeededExecMemBytes = neededExecMemBytes;
@@ -201,8 +187,6 @@
* set the sensors needed by this app
*
* @param neededSensors - all the sensors needed by this app
- *
- * @hide
*/
public void setNeededSensors(int[] neededSensors) {
mNeededSensors = neededSensors;
@@ -222,8 +206,6 @@
*
* @param outputEvents - the events that may be generated by
* this app
- *
- * @hide
*/
public void setOutputEvents(int[] outputEvents) {
mOutputEvents = outputEvents;
@@ -242,8 +224,6 @@
* set the context hub identifier
*
* @param contexthubId - system wide unique identifier
- *
- * @hide
*/
public void setContexthubId(int contexthubId) {
mContexthubId = contexthubId;
@@ -262,8 +242,6 @@
* set the handle for an app instance
*
* @param handle - handle to this instance
- *
- * @hide
*/
public void setHandle(int handle) {
mHandle = handle;
@@ -274,7 +252,7 @@
mPublisher = in.readString();
mName = in.readString();
- mAppId = in.readLong();
+ mAppId = in.readInt();
mAppVersion = in.readInt();
mNeededReadMemBytes = in.readInt();
mNeededWriteMemBytes = in.readInt();
@@ -296,7 +274,7 @@
public void writeToParcel(Parcel out, int flags) {
out.writeString(mPublisher);
out.writeString(mName);
- out.writeLong(mAppId);
+ out.writeInt(mAppId);
out.writeInt(mAppVersion);
out.writeInt(mContexthubId);
out.writeInt(mNeededReadMemBytes);
@@ -308,6 +286,7 @@
out.writeInt(mOutputEvents.length);
out.writeIntArray(mOutputEvents);
+
}
public static final Parcelable.Creator<NanoAppInstanceInfo> CREATOR
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5bcf102..4ba97d5 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -180,7 +180,12 @@
// caller must call setNewConfiguration() sometime later.
Configuration updateOrientationFromAppTokens(in Configuration currentConfig,
IBinder freezeThisOneIfNeeded);
- void setNewConfiguration(in Configuration config);
+ // Notify window manager of the new configuration. Returns an array of stack ids that's
+ // affected by the update, ActivityManager should resize these stacks.
+ int[] setNewConfiguration(in Configuration config);
+
+ // Retrieves the new bounds after the configuration update evaluated by window manager.
+ Rect getBoundsForNewConfiguration(int stackId);
void startFreezingScreen(int exitAnim, int enterAnim);
void stopFreezingScreen();
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 8bd63df..6d2cea6 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -17,6 +17,7 @@
package android.widget;
import android.annotation.ColorInt;
+import android.app.ActivityManager.StackId;
import android.app.ActivityOptions;
import android.app.ActivityThread;
import android.app.Application;
@@ -228,6 +229,11 @@
public boolean onClickHandler(View view, PendingIntent pendingIntent,
Intent fillInIntent) {
+ return onClickHandler(view, pendingIntent, fillInIntent, StackId.INVALID_STACK_ID);
+ }
+
+ public boolean onClickHandler(View view, PendingIntent pendingIntent,
+ Intent fillInIntent, int launchStackId) {
try {
// TODO: Unregister this handler if PendingIntent.FLAG_ONE_SHOT?
Context context = view.getContext();
@@ -239,6 +245,10 @@
0, 0,
view.getMeasuredWidth(), view.getMeasuredHeight());
}
+
+ if (launchStackId != StackId.INVALID_STACK_ID) {
+ opts.setLaunchStackId(launchStackId);
+ }
context.startIntentSender(
pendingIntent.getIntentSender(), fillInIntent,
Intent.FLAG_ACTIVITY_NEW_TASK,
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index ee73b90..bed5a2e 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -238,6 +238,14 @@
return total;
}
+ public static int[] convertToIntArray(List<Integer> list) {
+ int[] array = new int[list.size()];
+ for (int i = 0; i < list.size(); i++) {
+ array[i] = list.get(i);
+ }
+ return array;
+ }
+
/**
* Adds value to given array if not already present, providing set-like
* behavior.
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 9d14478..3d892af 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -1099,7 +1099,8 @@
|| mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC
|| mode == DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX
|| mode == DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
- || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
+ || mode == DevicePolicyManager.PASSWORD_QUALITY_COMPLEX
+ || mode == DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
return passwordEnabled && savedPasswordExists(userId);
}
diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp
index d05f82e..8724729 100644
--- a/core/jni/android_hardware_location_ContextHubService.cpp
+++ b/core/jni/android_hardware_location_ContextHubService.cpp
@@ -16,39 +16,23 @@
#include "context_hub.h"
-#define LOG_NDEBUG 0
-#define LOG_TAG "ContextHubService"
-
-#include <inttypes.h>
-#include <jni.h>
-#include <map>
-#include <queue>
#include <string.h>
#include <stdint.h>
#include <stdio.h>
-#include <stdlib.h>
-#include <cutils/log.h>
-
+#include <jni.h>
#include "JNIHelp.h"
#include "core_jni_helpers.h"
-
-static constexpr int OS_APP_ID=-1;
-
-static constexpr int MIN_APP_ID=1;
-static constexpr int MAX_APP_ID=128;
-
-static constexpr size_t MSG_HEADER_SIZE=4;
-static constexpr int HEADER_FIELD_MSG_TYPE=0;
-static constexpr int HEADER_FIELD_MSG_VERSION=1;
-static constexpr int HEADER_FIELD_HUB_HANDLE=2;
-static constexpr int HEADER_FIELD_APP_INSTANCE=3;
+#include "stdint.h"
+#include "stdlib.h"
namespace android {
namespace {
+// TODO: We should share this array_length function widely around Android
+// code.
/*
* Finds the length of a statically-sized array using template trickery that
* also prevents it from being applied to the wrong type.
@@ -80,207 +64,35 @@
jmethodID contextHubInfoSetPeakPowerDrawMw;
jmethodID contextHubInfoSetSupportedSensors;
jmethodID contextHubInfoSetMemoryRegions;
- jmethodID contextHubInfoSetMaxPacketLenBytes;
jmethodID contextHubServiceMsgReceiptCallback;
- jmethodID contextHubServiceAddAppInstance;
};
struct context_hub_info_s {
- uint32_t *cookies;
+ int cookie;
int numHubs;
const struct context_hub_t *hubs;
struct context_hub_module_t *contextHubModule;
};
-struct app_instance_info_s {
- uint32_t hubHandle; // Id of the hub this app is on
- int instanceId; // systemwide unique instance id - assigned
- struct hub_app_info appInfo; // returned from the HAL
- uint64_t truncName; // Possibly truncated name - logging
-};
-
struct contextHubServiceDb_s {
int initialized;
context_hub_info_s hubInfo;
jniInfo_s jniInfo;
- std::queue<int> freeIds;
- std::map<int, app_instance_info_s *> appInstances;
};
} // unnamed namespace
static contextHubServiceDb_s db;
-int context_hub_callback(uint32_t hubId, const struct hub_message_t *msg,
+int context_hub_callback(uint32_t hub_id, const struct hub_message_t *msg,
void *cookie);
-const context_hub_t *get_hub_info(int hubHandle) {
- if (hubHandle >= 0 && hubHandle < db.hubInfo.numHubs) {
- return &db.hubInfo.hubs[hubHandle];
- }
- return nullptr;
-}
-
-static int send_msg_to_hub(const hub_message_t *msg, int hubHandle) {
- const context_hub_t *info = get_hub_info(hubHandle);
-
- if (info) {
- return db.hubInfo.contextHubModule->send_message(info->hub_id, msg);
- } else {
- ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle);
- return -1;
- }
-}
-
-static int set_os_app_as_destination(hub_message_t *msg, int hubHandle) {
- const context_hub_t *info = get_hub_info(hubHandle);
-
- if (info) {
- msg->app = info->os_app_name;
- return 0;
- } else {
- ALOGD("%s: Hub information is null for hubHandle %d", __FUNCTION__, hubHandle);
- return -1;
- }
-}
-
-static int get_hub_id_for_app_instance(int id) {
- if (db.appInstances.find(id) == db.appInstances.end()) {
- ALOGD("%s: Cannot find app for app instance %d", __FUNCTION__, id);
- return -1;
- }
-
- int hubHandle = db.appInstances[id]->hubHandle;
-
- return db.hubInfo.hubs[hubHandle].hub_id;
-}
-
-static int set_dest_app(hub_message_t *msg, int id) {
- if (db.appInstances.find(id) == db.appInstances.end()) {
- ALOGD("%s: Cannod find app for app instance %d", __FUNCTION__, id);
- return -1;
- }
-
- msg->app = db.appInstances[id]->appInfo.name;
- return 0;
-}
-
-static void send_query_for_apps() {
- hub_message_t msg;
-
- msg.message_type = CONTEXT_HUB_QUERY_APPS;
- msg.message_len = 0;
-
- for (int i = 0; i < db.hubInfo.numHubs; i++ ) {
- ALOGD("Sending query for apps to hub %d", i);
- set_os_app_as_destination(&msg, i);
- if (send_msg_to_hub(&msg, i) != 0) {
- ALOGW("Could not query hub %i for apps", i);
- }
- }
-}
-
-static int return_id(int id) {
- // Note : This method is not thread safe.
- // id returned is guarenteed to be in use
- db.freeIds.push(id);
- return 0;
-}
-
-static int generate_id(void) {
- // Note : This method is not thread safe.
- int retVal = -1;
-
- if (!db.freeIds.empty()) {
- retVal = db.freeIds.front();
- db.freeIds.pop();
- }
-
- return retVal;
-}
-
-int add_app_instance(const hub_app_info *appInfo, uint32_t hubHandle, JNIEnv *env) {
- // Not checking if the apps are indeed distinct
-
- app_instance_info_s *entry;
- void *appName;
- hub_app_name_t *name;
-
- assert(appInfo && appInfo->name && appInfo->name->app_name);
-
- entry = (app_instance_info_s *) malloc(sizeof(app_instance_info_s));
- appName = malloc(appInfo->name->app_name_len);
- name = (hub_app_name_t *) malloc(sizeof(hub_app_name_t));
-
- int appInstanceHandle = generate_id();
-
- if (appInstanceHandle < 0 || !appName || !entry || !name) {
- ALOGE("Cannot find resources to add app instance %d, %p, %p",
- appInstanceHandle, appName, entry);
-
- free(appName);
- free(entry);
- free(name);
-
- if (appInstanceHandle >= 0) {
- return_id(appInstanceHandle);
- }
-
- return -1;
- }
-
- memcpy(&(entry->appInfo), appInfo, sizeof(entry->appInfo));
- memcpy(appName, appInfo->name->app_name, appInfo->name->app_name_len);
- name->app_name = appName;
- name->app_name_len = appInfo->name->app_name_len;
- entry->appInfo.name = name;
- entry->truncName = 0;
- memcpy(&(entry->truncName), name->app_name,
- sizeof(entry->truncName) < name->app_name_len ?
- sizeof(entry->truncName) : name->app_name_len);
-
- // Not checking for sanity of hubId
- entry->hubHandle = hubHandle;
- entry->instanceId = appInstanceHandle;
- db.appInstances[appInstanceHandle] = entry;
-
- // Finally - let the service know of this app instance
- env->CallIntMethod(db.jniInfo.jContextHubService,
- db.jniInfo.contextHubServiceAddAppInstance,
- hubHandle, entry->instanceId, entry->truncName,
- entry->appInfo.version);
-
- ALOGW("Added App 0x%" PRIx64 " on hub Handle %" PRId32
- " as appInstance %d, original name_length %" PRId32, entry->truncName,
- entry->hubHandle, appInstanceHandle, name->app_name_len);
-
- return appInstanceHandle;
-}
-
-int delete_app_instance(int id) {
- if (db.appInstances.find(id) == db.appInstances.end()) {
- return -1;
- }
-
- return_id(id);
-
- if (db.appInstances[id]) {
- // Losing the const cast below. This is intentional.
- free((void *)db.appInstances[id]->appInfo.name->app_name);
- free((void *)db.appInstances[id]->appInfo.name);
- free(db.appInstances[id]);
- db.appInstances.erase(id);
- }
-
- return 0;
-}
-
-
static void initContextHubService() {
int err = 0;
- db.hubInfo.hubs = nullptr;
+ db.hubInfo.hubs = NULL;
db.hubInfo.numHubs = 0;
+ db.hubInfo.cookie = 0;
int i;
err = hw_get_module(CONTEXT_HUB_MODULE_ID,
@@ -291,45 +103,26 @@
strerror(-err));
}
- // Prep for storing app info
- for(i = MIN_APP_ID; i <= MAX_APP_ID; i++) {
- db.freeIds.push(i);
- }
-
if (db.hubInfo.contextHubModule) {
- int retNumHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
+ ALOGD("Fetching hub info");
+ db.hubInfo.numHubs = db.hubInfo.contextHubModule->get_hubs(db.hubInfo.contextHubModule,
&db.hubInfo.hubs);
- ALOGD("ContextHubModule returned %d hubs ", retNumHubs);
- db.hubInfo.numHubs = retNumHubs;
- if (db.hubInfo.numHubs > 0) {
- db.hubInfo.numHubs = retNumHubs;
- db.hubInfo.cookies = (uint32_t *)malloc(sizeof(uint32_t) * db.hubInfo.numHubs);
-
- if (!db.hubInfo.cookies) {
- ALOGW("Ran out of memory allocating cookies, bailing");
- return;
- }
-
- for (i = 0; i < db.hubInfo.numHubs; i++) {
- db.hubInfo.cookies[i] = db.hubInfo.hubs[i].hub_id;
- if (db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id,
- context_hub_callback,
- &db.hubInfo.cookies[i]) == 0) {
- }
- }
+ if (db.hubInfo.numHubs > 0) {
+ for (i = 0; i < db.hubInfo.numHubs; i++) {
+ // TODO : Event though one cookie is OK for now, lets change
+ // this to be one per hub
+ db.hubInfo.contextHubModule->subscribe_messages(db.hubInfo.hubs[i].hub_id,
+ context_hub_callback,
+ &db.hubInfo.cookie);
}
-
- send_query_for_apps();
- } else {
- ALOGW("No Context Hub Module present");
+ }
}
}
static int onMessageReceipt(int *header, int headerLen, char *msg, int msgLen) {
JNIEnv *env;
-
- if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
+ if ((db.jniInfo.vm)->AttachCurrentThread(&env, NULL) != JNI_OK) {
return -1;
}
@@ -339,130 +132,28 @@
env->SetByteArrayRegion(jmsg, 0, msgLen, (jbyte *)msg);
env->SetIntArrayRegion(jheader, 0, headerLen, (jint *)header);
- return (env->CallIntMethod(db.jniInfo.jContextHubService,
+
+ return env->CallIntMethod(db.jniInfo.jContextHubService,
db.jniInfo.contextHubServiceMsgReceiptCallback,
- jheader, jmsg) != 0);
+ jheader, jmsg);
}
-int handle_query_apps_response(char *msg, int msgLen, uint32_t hubHandle) {
- int i;
- JNIEnv *env;
- if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
- return -1;
- }
-
- int numApps = msgLen/sizeof(hub_app_info);
- hub_app_info *info = (hub_app_info *)malloc(msgLen); // handle possible alignment
-
- if (!info) {
- return -1;
- }
-
- memcpy(info, msg, msgLen);
- for (i = 0; i < numApps; i++) {
- add_app_instance(&info[i], hubHandle, env);
- }
-
- free(info);
-
- return 0;
-}
-
-
-int handle_os_message(uint32_t msgType, uint32_t hubHandle,
- char *msg, int msgLen) {
- int retVal;
-
- switch(msgType) {
- case CONTEXT_HUB_APPS_ENABLE:
- retVal = 0;
- break;
-
- case CONTEXT_HUB_APPS_DISABLE:
- retVal = 0;
- break;
-
- case CONTEXT_HUB_LOAD_APP:
- retVal = 0;
- break;
-
- case CONTEXT_HUB_UNLOAD_APP:
- retVal = 0;
- break;
-
- case CONTEXT_HUB_QUERY_APPS:
- retVal = handle_query_apps_response(msg, msgLen, hubHandle);
- break;
-
- case CONTEXT_HUB_QUERY_MEMORY:
- retVal = 0;
- break;
-
- case CONTEXT_HUB_LOAD_OS:
- retVal = 0;
- break;
-
- default:
- retVal = -1;
- break;
-
- }
-
- return retVal;
-}
-
-static bool sanity_check_cookie(void *cookie, uint32_t hub_id) {
- int *ptr = (int *)cookie;
-
- if (!ptr || *ptr >= db.hubInfo.numHubs) {
- return false;
- }
-
- if (db.hubInfo.hubs[*ptr].hub_id != hub_id) {
- return false;
- } else {
- return true;
- }
-}
-
-int context_hub_callback(uint32_t hubId,
- const struct hub_message_t *msg,
+int context_hub_callback(uint32_t hub_id, const struct hub_message_t *msg,
void *cookie) {
- int msgHeader[MSG_HEADER_SIZE];
+ int msgHeader[4];
- if (!msg) {
- return -1;
- }
+ msgHeader[0] = msg->message_type;
+ msgHeader[1] = 0; // TODO : HAL does not have a version field
+ msgHeader[2] = hub_id;
- msgHeader[HEADER_FIELD_MSG_TYPE] = msg->message_type;
-
- if (!sanity_check_cookie(cookie, hubId)) {
- ALOGW("Incorrect cookie %" PRId32 " for cookie %p! Bailing",
- hubId, cookie);
-
- return -1;
- }
-
- msgHeader[HEADER_FIELD_HUB_HANDLE] = *(uint32_t*)cookie;
-
- if (msgHeader[HEADER_FIELD_MSG_TYPE] < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE &&
- msgHeader[HEADER_FIELD_MSG_TYPE] != 0 ) {
- handle_os_message(msgHeader[HEADER_FIELD_MSG_TYPE],
- msgHeader[HEADER_FIELD_HUB_HANDLE],
- (char *)msg->message,
- msg->message_len);
- } else {
- onMessageReceipt(msgHeader, sizeof(msgHeader),
- (char *)msg->message, msg->message_len);
- }
-
- return 0;
+ onMessageReceipt(msgHeader, sizeof(msgHeader), (char *)msg->message, msg->message_len); // TODO : Populate this
+ return 0;
}
static int init_jni(JNIEnv *env, jobject instance) {
if (env->GetJavaVM(&db.jniInfo.vm) != JNI_OK) {
- return -1;
+ return -1;
}
db.jniInfo.jContextHubService = env->NewGlobalRef(instance);
@@ -476,6 +167,7 @@
db.jniInfo.memoryRegionsClass =
env->FindClass("android/hardware/location/MemoryRegion");
+ //TODO :: Add error checking
db.jniInfo.contextHubInfoCtor =
env->GetMethodID(db.jniInfo.contextHubInfoClass, "<init>", "()V");
db.jniInfo.contextHubInfoSetId =
@@ -517,9 +209,6 @@
db.jniInfo.contextHubInfoSetMemoryRegions =
env->GetMethodID(db.jniInfo.contextHubInfoClass,
"setMemoryRegions", "([Landroid/hardware/location/MemoryRegion;)V");
- db.jniInfo.contextHubInfoSetMaxPacketLenBytes =
- env->GetMethodID(db.jniInfo.contextHubInfoClass,
- "setMaxPacketLenBytes", "(I)V");
db.jniInfo.contextHubServiceMsgReceiptCallback =
@@ -529,11 +218,6 @@
env->GetMethodID(db.jniInfo.contextHubInfoClass, "setName",
"(Ljava/lang/String;)V");
- db.jniInfo.contextHubServiceAddAppInstance =
- env->GetMethodID(db.jniInfo.contextHubServiceClass,
- "addAppInstance", "(IIJI)I");
-
-
return 0;
}
@@ -561,28 +245,20 @@
env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPlatformVersion, hub->platform_version);
env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetToolchainVersion, hub->toolchain_version);
env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakMips, hub->peak_mips);
- env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw,
- hub->stopped_power_draw_mw);
- env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw,
- hub->sleep_power_draw_mw);
- env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw,
- hub->peak_power_draw_mw);
- env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMaxPacketLenBytes,
- hub->max_supported_msg_len);
-
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetStoppedPowerDrawMw, hub->stopped_power_draw_mw);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetSleepPowerDrawMw, hub->sleep_power_draw_mw);
+ env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetPeakPowerDrawMw, hub->peak_power_draw_mw);
// TODO : jintBuf = env->NewIntArray(hub->num_connected_sensors);
- // TODO : env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors,
- // hub->connected_sensors);
+ // TODO : env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, hub->connected_sensors);
jintBuf = env->NewIntArray(array_length(dummyConnectedSensors));
env->SetIntArrayRegion(jintBuf, 0, hub->num_connected_sensors, dummyConnectedSensors);
// We are not getting the memory regions from the CH Hal - change this when it is available
- jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, nullptr);
+ jmemBuf = env->NewObjectArray(0, db.jniInfo.memoryRegionsClass, NULL);
// Note the zero size above. We do not need to set any elements
env->CallVoidMethod(jHub, db.jniInfo.contextHubInfoSetMemoryRegions, jmemBuf);
-
return jHub;
}
@@ -591,18 +267,18 @@
jobject hub;
jobjectArray retArray;
+ initContextHubService();
+
if (init_jni(env, instance) < 0) {
- return nullptr;
+ return NULL;
}
+ // Note : The service is clamping the number of hubs to 1
+ db.hubInfo.numHubs = 1;
+
initContextHubService();
- if (db.hubInfo.numHubs > 1) {
- ALOGW("Clamping the number of hubs to 1");
- db.hubInfo.numHubs = 1;
- }
-
- retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, nullptr);
+ retArray = env->NewObjectArray(db.hubInfo.numHubs, db.jniInfo.contextHubInfoClass, NULL);
for(int i = 0; i < db.hubInfo.numHubs; i++) {
hub = constructJContextHubInfo(env, &db.hubInfo.hubs[i]);
@@ -615,27 +291,28 @@
static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_,
jbyteArray data_) {
hub_message_t msg;
- jint retVal = -1; // Default to failure
+ hub_app_name_t dest;
+ uint8_t os_name[8];
+
+ memset(os_name, 0, sizeof(os_name));
jint *header = env->GetIntArrayElements(header_, 0);
- unsigned int numHeaderElements = env->GetArrayLength(header_);
+ //int numHeaderElements = env->GetArrayLength(header_);
jbyte *data = env->GetByteArrayElements(data_, 0);
int dataBufferLength = env->GetArrayLength(data_);
- if (numHeaderElements >= MSG_HEADER_SIZE) {
- if (set_dest_app(&msg, header[HEADER_FIELD_APP_INSTANCE]) == 0) {
- msg.message_type = header[HEADER_FIELD_MSG_TYPE];
- msg.message_len = dataBufferLength;
- msg.message = data;
- retVal = db.hubInfo.contextHubModule->send_message(
- get_hub_id_for_app_instance(header[HEADER_FIELD_APP_INSTANCE]),
- &msg);
- } else {
- ALOGD("Could not find app instance %d", header[HEADER_FIELD_APP_INSTANCE]);
- }
- } else {
- ALOGD("Malformed header len");
- }
+ /* Assume an int - thats all we understand */
+ dest.app_name_len = array_length(os_name); // TODO : Check this
+ //dest.app_name = &header[1];
+ dest.app_name = os_name;
+
+ msg.app = &dest;
+
+ msg.message_type = header[3];
+ msg.message_len = dataBufferLength;
+ msg.message = data;
+
+ jint retVal = db.hubInfo.contextHubModule->send_message(header[0], &msg);
env->ReleaseIntArrayElements(header_, header, 0);
env->ReleaseByteArrayElements(data_, data, 0);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e03183b..30a5993 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -845,14 +845,14 @@
-->
<permission android:name="android.permission.ACCESS_UCE_PRESENCE_SERVICE"
android:permissionGroup="android.permission-group.PHONE"
- android:protectionLevel="dangerous"/>
+ android:protectionLevel="signatureOrSystem"/>
<!-- @hide Allows an application to Access UCE-OPTIONS.
<p>Protection level: dangerous
-->
<permission android:name="android.permission.ACCESS_UCE_OPTIONS_SERVICE"
android:permissionGroup="android.permission-group.PHONE"
- android:protectionLevel="dangerous"/>
+ android:protectionLevel="signatureOrSystem"/>
@@ -2004,6 +2004,11 @@
<permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED"
android:protectionLevel="signature|privileged" />
+ <!-- @SystemApi Allows but does not guarantee access to user passwords at the conclusion of add
+ account -->
+ <permission android:name="android.permission.GET_PASSWORD_PRIVILEGED"
+ android:protectionLevel="signature|privileged" />
+
<!-- @SystemApi Allows applications to RW to diagnostic resources.
<p>Not for use by third-party applications. -->
<permission android:name="android.permission.DIAGNOSTIC"
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 0a8c692..00eff91 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -2157,7 +2157,7 @@
final RecordConfigChangeCallbackData cbData =
(RecordConfigChangeCallbackData) msg.obj;
if (cbData.mCb != null) {
- cbData.mCb.onRecordConfigChanged(cbData.mConfigs);
+ cbData.mCb.onRecordingConfigChanged(cbData.mConfigs);
}
break;
default:
@@ -2746,7 +2746,7 @@
* @param configs array containing the results of
* {@link AudioManager#getActiveRecordingConfigurations()}.
*/
- public void onRecordConfigChanged(AudioRecordingConfiguration[] configs) {}
+ public void onRecordingConfigChanged(AudioRecordingConfiguration[] configs) {}
}
private static class AudioRecordingCallbackInfo {
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index b6ff41e..0ea4ec5 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -596,14 +596,14 @@
* AudioTrack player = new AudioTrack.Builder()
* .setAudioAttributes(new AudioAttributes.Builder()
* .setUsage(AudioAttributes.USAGE_ALARM)
- * .setContentType(CONTENT_TYPE_MUSIC)
+ * .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
* .build())
* .setAudioFormat(new AudioFormat.Builder()
* .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
* .setSampleRate(441000)
* .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
* .build())
- * .setBufferSize(minBuffSize)
+ * .setBufferSizeInBytes(minBuffSize)
* .build();
* </pre>
* <p>
diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
index 9606eab54..87136ef3 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java
@@ -636,10 +636,12 @@
return true;
}
} else if (keyCode == KeyEvent.KEYCODE_TAB) {
+ Metrics.logKeyboardAction(this, keyCode);
// Tab toggles focus on the navigation drawer.
toggleNavDrawerFocus();
return true;
} else if (keyCode == KeyEvent.KEYCODE_DEL) {
+ Metrics.logKeyboardAction(this, keyCode);
popDir();
return true;
}
diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
index e7d7ec4..d4439d8 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java
@@ -349,18 +349,21 @@
case KeyEvent.KEYCODE_A:
dir = getDirectoryFragment();
if (dir != null) {
+ Metrics.logKeyboardAction(this, keyCode);
dir.selectAllFiles();
}
return true;
case KeyEvent.KEYCODE_C:
dir = getDirectoryFragment();
if (dir != null) {
+ Metrics.logKeyboardAction(this, keyCode);
dir.copySelectedToClipboard();
}
return true;
case KeyEvent.KEYCODE_V:
dir = getDirectoryFragment();
if (dir != null) {
+ Metrics.logKeyboardAction(this, keyCode);
dir.pasteFromClipboard();
}
return true;
diff --git a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
index 1e01c22..a4a67f9 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java
@@ -29,6 +29,7 @@
import android.net.Uri;
import android.provider.DocumentsContract;
import android.util.Log;
+import android.view.KeyEvent;
import com.android.documentsui.State.ActionType;
import com.android.documentsui.model.DocumentInfo;
@@ -70,6 +71,7 @@
private static final String COUNT_DRAG_N_DROP = "docsui_drag_n_drop";
private static final String COUNT_SEARCH = "docsui_search";
private static final String COUNT_MENU_ACTION = "docsui_menu_action";
+ private static final String COUNT_KEYBOARD_ACTION = "docsui_keyboard_action";
// Indices for bucketing roots in the roots histogram. "Other" is the catch-all index for any
// root that is not explicitly recognized by the Metrics code (see {@link
@@ -289,6 +291,31 @@
@Retention(RetentionPolicy.SOURCE)
public @interface MetricsAction {}
+ // Codes representing different keyboard shortcut triggered actions. These are used for
+ // bucketing stats in the COUNT_KEYBOARD_ACTION histogram.
+ // Do not change or rearrange these values, that will break historical data. Only add to the
+ // list.
+ // Do not use negative numbers or zero; clearcut only handles positive integers.
+ private static final int ACTION_KEYBOARD_OTHER = 1;
+ private static final int ACTION_KEYBOARD_PASTE = 2;
+ private static final int ACTION_KEYBOARD_COPY = 3;
+ private static final int ACTION_KEYBOARD_DELETE = 4;
+ private static final int ACTION_KEYBOARD_SELECT_ALL = 5;
+ private static final int ACTION_KEYBOARD_BACK = 6;
+ private static final int ACTION_KEYBOARD_SWITCH_FOCUS = 7;
+
+ @IntDef(flag = false, value = {
+ ACTION_KEYBOARD_OTHER,
+ ACTION_KEYBOARD_PASTE,
+ ACTION_KEYBOARD_COPY,
+ ACTION_KEYBOARD_DELETE,
+ ACTION_KEYBOARD_SELECT_ALL,
+ ACTION_KEYBOARD_BACK,
+ ACTION_KEYBOARD_SWITCH_FOCUS
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface KeyboardAction {}
+
// Codes representing different actions to open the drawer. They are used for bucketing stats in
// the COUNT_DRAWER_OPENED histogram.
// Do not change or rearrange these values, that will break historical data. Only add to the
@@ -493,6 +520,39 @@
}
/**
+ * Logs keyboard shortcut actions. Since keyboard shortcuts have their corresponding menu items,
+ * they are identified by menu item resource id for convenience.
+ * @param context
+ * @param keyCode
+ */
+ public static void logKeyboardAction(Context context, int keyCode) {
+ @KeyboardAction int keyboardAction = ACTION_KEYBOARD_OTHER;
+ switch (keyCode) {
+ case KeyEvent.KEYCODE_V:
+ keyboardAction = ACTION_KEYBOARD_PASTE;
+ break;
+ case KeyEvent.KEYCODE_C:
+ keyboardAction = ACTION_KEYBOARD_COPY;
+ break;
+ case KeyEvent.KEYCODE_FORWARD_DEL:
+ keyboardAction = ACTION_KEYBOARD_DELETE;
+ break;
+ case KeyEvent.KEYCODE_A:
+ keyboardAction = ACTION_KEYBOARD_SELECT_ALL;
+ break;
+ case KeyEvent.KEYCODE_DEL:
+ keyboardAction = ACTION_KEYBOARD_BACK;
+ break;
+ case KeyEvent.KEYCODE_TAB:
+ keyboardAction = ACTION_KEYBOARD_SWITCH_FOCUS;
+ break;
+ default:
+ break;
+ }
+ logHistogram(context, COUNT_KEYBOARD_ACTION, keyboardAction);
+ }
+
+ /**
* Logs startup time in milliseconds.
* @param context
* @param startupMs Startup time in milliseconds.
diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
index d70a899..20316ff 100644
--- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
+++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java
@@ -1339,6 +1339,7 @@
// This has to be handled here instead of in a keyboard shortcut, because
// keyboard shortcuts all have to be modified with the 'Ctrl' key.
if (mSelectionManager.hasSelection()) {
+ Metrics.logKeyboardAction(getContext(), keyCode);
deleteDocuments(mSelectionManager.getSelection());
}
// Always handle the key, even if there was nothing to delete. This is a
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
index 454221a..2b549f1 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -77,6 +77,7 @@
case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
+ case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
return SecurityMode.Password;
case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
index 3eeabc7..e5ac0d3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java
@@ -141,9 +141,9 @@
return;
}
+ int viewWidth = mTaskViewRect.width();
+ int viewHeight = mTaskViewRect.height();
if (mBitmapShader != null) {
- int viewWidth = mTaskViewRect.width();
- int viewHeight = mTaskViewRect.height();
// We are drawing the thumbnail in the same orientation, so just fit the width
int thumbnailWidth = (int) (mThumbnailRect.width() * mThumbnailScale);
@@ -180,6 +180,9 @@
canvas.restoreToCount(count);
}
+ } else {
+ canvas.drawRoundRect(0, 0, viewWidth, viewHeight, mCornerRadius, mCornerRadius,
+ mBgFillPaint);
}
}
@@ -319,12 +322,12 @@
mDisabledInSafeMode = disabledInSafeMode;
if (t.thumbnail != null) {
setThumbnail(t.thumbnail, thumbnailInfo);
- if (t.colorBackground != 0) {
- mBgFillPaint.setColor(t.colorBackground);
- }
} else {
setThumbnail(null, null);
}
+ if (t.colorBackground != 0) {
+ mBgFillPaint.setColor(t.colorBackground);
+ }
}
/** Unbinds the thumbnail view from the task */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 0e21517..4ed6426 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -19,7 +19,9 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.ActivityManager;
+import android.app.ActivityManager.StackId;
import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
import android.app.KeyguardManager;
import android.app.Notification;
import android.app.NotificationManager;
@@ -347,7 +349,7 @@
}, afterKeyguardGone);
return true;
} else {
- return super.onClickHandler(view, pendingIntent, fillInIntent);
+ return superOnClickHandler(view, pendingIntent, fillInIntent);
}
}
@@ -384,7 +386,8 @@
private boolean superOnClickHandler(View view, PendingIntent pendingIntent,
Intent fillInIntent) {
- return super.onClickHandler(view, pendingIntent, fillInIntent);
+ return super.onClickHandler(view, pendingIntent, fillInIntent,
+ StackId.FULLSCREEN_WORKSPACE_STACK_ID);
}
private boolean handleRemoteInput(View view, PendingIntent pendingIntent, Intent fillInIntent) {
@@ -990,7 +993,7 @@
}
TaskStackBuilder.create(mContext)
.addNextIntentWithParentStack(intent)
- .startActivities(null,
+ .startActivities(getActivityOptions(),
new UserHandle(UserHandle.getUserId(appUid)));
overrideActivityPendingAppTransition(keyguardShowing);
} catch (RemoteException e) {
@@ -1740,7 +1743,7 @@
} catch (RemoteException e) {
}
try {
- intent.send();
+ intent.send(null, 0, null, null, null, null, getActivityOptions());
} catch (PendingIntent.CanceledException e) {
// the stack trace isn't very helpful here.
// Just log the exception message.
@@ -1848,7 +1851,8 @@
}
}
try {
- intent.send();
+ intent.send(null, 0, null, null, null, null,
+ getActivityOptions());
} catch (PendingIntent.CanceledException e) {
// the stack trace isn't very helpful here.
// Just log the exception message.
@@ -1924,6 +1928,14 @@
}
}
+ protected Bundle getActivityOptions() {
+ // Anything launched from the notification shade should always go into the
+ // fullscreen stack.
+ ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchStackId(StackId.FULLSCREEN_WORKSPACE_STACK_ID);
+ return options.toBundle();
+ }
+
protected void visibilityChanged(boolean visible) {
if (mVisible != visible) {
mVisible = visible;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 4c5c843..c563eb6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -21,7 +21,9 @@
import android.animation.AnimatorListenerAdapter;
import android.annotation.NonNull;
import android.app.ActivityManager;
+import android.app.ActivityManager.StackId;
import android.app.ActivityManagerNative;
+import android.app.ActivityOptions;
import android.app.IActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
@@ -3091,8 +3093,8 @@
null, mContext.getBasePackageName(),
intent,
intent.resolveTypeIfNeeded(mContext.getContentResolver()),
- null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null, null,
- UserHandle.CURRENT.getIdentifier());
+ null, null, 0, Intent.FLAG_ACTIVITY_NEW_TASK, null,
+ getActivityOptions(), UserHandle.CURRENT.getIdentifier());
} catch (RemoteException e) {
Log.w(TAG, "Unable to start activity", e);
}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 799a763..0a814ab 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -92,6 +92,7 @@
private static final int MESSAGE_BLUETOOTH_STATE_CHANGE = 60;
private static final int MESSAGE_TIMEOUT_BIND = 100;
private static final int MESSAGE_TIMEOUT_UNBIND = 101;
+ private static final int MESSAGE_GET_NAME_AND_ADDRESS = 200;
private static final int MESSAGE_USER_SWITCHED = 300;
private static final int MESSAGE_USER_UNLOCKED = 301;
private static final int MESSAGE_ADD_PROXY_DELAYED = 400;
@@ -599,8 +600,8 @@
sendEnableMsg(true);
}
return true;
-
}
+
public boolean enable() {
if ((Binder.getCallingUid() != Process.SYSTEM_UID) &&
(!checkIfCallerIsForegroundUser())) {
@@ -763,9 +764,8 @@
sendEnableMsg(mQuietEnableExternal);
} else if (!isNameAndAddressSet()) {
if (DBG) Slog.d(TAG, "Getting adapter name and address");
- enable();
- waitForOnOff(true, false);
- disable(true);
+ Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
+ mHandler.sendMessage(getMsg);
}
}
@@ -1076,6 +1076,8 @@
private BluetoothServiceConnection mConnection = new BluetoothServiceConnection();
private class BluetoothHandler extends Handler {
+ boolean mGetNameAddressOnly = false;
+
public BluetoothHandler(Looper looper) {
super(looper);
}
@@ -1084,6 +1086,37 @@
public void handleMessage(Message msg) {
if (DBG) Slog.d (TAG, "Message: " + msg.what);
switch (msg.what) {
+ case MESSAGE_GET_NAME_AND_ADDRESS:
+ if (DBG) Slog.d(TAG, "MESSAGE_GET_NAME_AND_ADDRESS");
+ synchronized(mConnection) {
+ if ((mBluetooth == null) && (!mBinding)) {
+ if (DBG) Slog.d(TAG, "Binding to service to get name and address");
+ mGetNameAddressOnly = true;
+ Message timeoutMsg = mHandler.obtainMessage(MESSAGE_TIMEOUT_BIND);
+ mHandler.sendMessageDelayed(timeoutMsg, TIMEOUT_BIND_MS);
+ Intent i = new Intent(IBluetooth.class.getName());
+ if (!doBind(i, mConnection,
+ Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT,
+ UserHandle.CURRENT)) {
+ mHandler.removeMessages(MESSAGE_TIMEOUT_BIND);
+ } else {
+ mBinding = true;
+ }
+ } else if (mBluetooth != null) {
+ try {
+ storeNameAndAddress(mBluetooth.getName(),
+ mBluetooth.getAddress());
+ } catch (RemoteException re) {
+ Slog.e(TAG, "Unable to grab names", re);
+ }
+ if (mGetNameAddressOnly && !mEnable) {
+ unbindAndFinish();
+ }
+ mGetNameAddressOnly = false;
+ }
+ }
+ break;
+
case MESSAGE_ENABLE:
if (DBG) {
Slog.d(TAG, "MESSAGE_ENABLE: mBluetooth = " + mBluetooth);
@@ -1177,6 +1210,12 @@
mBluetoothBinder = service;
mBluetooth = IBluetooth.Stub.asInterface(service);
+ if (!isNameAndAddressSet()) {
+ Message getMsg = mHandler.obtainMessage(MESSAGE_GET_NAME_AND_ADDRESS);
+ mHandler.sendMessage(getMsg);
+ if (mGetNameAddressOnly) return;
+ }
+
try {
boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver,
Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1);
@@ -1187,15 +1226,6 @@
Slog.e(TAG,"Unable to call configHciSnoopLog", e);
}
- if (!isNameAndAddressSet()) {
- try {
- storeNameAndAddress(mBluetooth.getName(),
- mBluetooth.getAddress());
- } catch (RemoteException re) {
- Slog.e(TAG, "Unable to grab names", re);
- }
- }
-
//Register callback object
try {
mBluetooth.registerCallback(mBluetoothCallback);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index bb32303..b8b7638 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -2500,21 +2500,31 @@
userId);
return;
}
-
final int pid = Binder.getCallingPid();
final Bundle options = (optionsIn == null) ? new Bundle() : optionsIn;
options.putInt(AccountManager.KEY_CALLER_UID, uid);
options.putInt(AccountManager.KEY_CALLER_PID, pid);
+ // Check to see if the Password should be included to the caller.
+ String callerPkg = optionsIn.getString(AccountManager.KEY_ANDROID_PACKAGE_NAME);
+ boolean isPasswordForwardingAllowed = isPermitted(
+ callerPkg, uid, Manifest.permission.GET_PASSWORD_PRIVILEGED);
+
int usrId = UserHandle.getCallingUserId();
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(usrId);
logRecordWithUid(accounts, DebugDbHelper.ACTION_CALLED_START_ACCOUNT_ADD,
TABLE_ACCOUNTS, uid);
- new StartAccountSession(accounts, response, accountType, expectActivityLaunch,
- null /* accountName */, false /* authDetailsRequired */,
- true /* updateLastAuthenticationTime */) {
+ new StartAccountSession(
+ accounts,
+ response,
+ accountType,
+ expectActivityLaunch,
+ null /* accountName */,
+ false /* authDetailsRequired */,
+ true /* updateLastAuthenticationTime */,
+ isPasswordForwardingAllowed) {
@Override
public void run() throws RemoteException {
mAuthenticator.startAddAccountSession(this, mAccountType, authTokenType,
@@ -2537,12 +2547,21 @@
/** Session that will encrypt the KEY_ACCOUNT_SESSION_BUNDLE in result. */
private abstract class StartAccountSession extends Session {
- public StartAccountSession(UserAccounts accounts, IAccountManagerResponse response,
- String accountType, boolean expectActivityLaunch, String accountName,
- boolean authDetailsRequired, boolean updateLastAuthenticationTime) {
+ private final boolean mIsPasswordForwardingAllowed;
+
+ public StartAccountSession(
+ UserAccounts accounts,
+ IAccountManagerResponse response,
+ String accountType,
+ boolean expectActivityLaunch,
+ String accountName,
+ boolean authDetailsRequired,
+ boolean updateLastAuthenticationTime,
+ boolean isPasswordForwardingAllowed) {
super(accounts, response, accountType, expectActivityLaunch,
true /* stripAuthTokenFromResult */, accountName, authDetailsRequired,
updateLastAuthenticationTime);
+ mIsPasswordForwardingAllowed = isPasswordForwardingAllowed;
}
@Override
@@ -2555,6 +2574,10 @@
checkKeyIntent(
Binder.getCallingUid(),
intent);
+ // Omit passwords if the caller isn't permitted to see them.
+ if (!mIsPasswordForwardingAllowed) {
+ result.remove(AccountManager.KEY_PASSWORD);
+ }
}
IAccountManagerResponse response;
if (mExpectActivityLaunch && result != null
@@ -2901,6 +2924,12 @@
}
int userId = UserHandle.getCallingUserId();
+
+ // Check to see if the Password should be included to the caller.
+ String callerPkg = loginOptions.getString(AccountManager.KEY_ANDROID_PACKAGE_NAME);
+ boolean isPasswordForwardingAllowed = isPermitted(
+ callerPkg, uid, Manifest.permission.GET_PASSWORD_PRIVILEGED);
+
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
@@ -2911,7 +2940,8 @@
expectActivityLaunch,
account.name,
false /* authDetailsRequired */,
- true /* updateLastCredentialTime */) {
+ true /* updateLastCredentialTime */,
+ isPasswordForwardingAllowed) {
@Override
public void run() throws RemoteException {
mAuthenticator.startUpdateCredentialsSession(this, account, authTokenType,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 39df999..ef05773 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -18045,6 +18045,9 @@
ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
int changes = 0;
+ if (mWindowManager != null) {
+ mWindowManager.deferSurfaceLayout();
+ }
if (values != null) {
Configuration newConfig = new Configuration(mConfiguration);
changes = newConfig.updateFrom(values);
@@ -18145,6 +18148,20 @@
null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
}
}
+ // Update the configuration with WM first and check if any of the stacks need to be
+ // resized due to the configuration change. If so, resize the stacks now and do any
+ // relaunches if necessary. This way we don't need to relaunch again below in
+ // ensureActivityConfigurationLocked().
+ if (mWindowManager != null) {
+ final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
+ if (resizedStacks != null) {
+ for (int stackId : resizedStacks) {
+ final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
+ mStackSupervisor.resizeStackLocked(
+ stackId, newBounds, null, null, false, false);
+ }
+ }
+ }
}
boolean kept = true;
@@ -18166,11 +18183,9 @@
!PRESERVE_WINDOWS);
}
}
-
- if (values != null && mWindowManager != null) {
- mWindowManager.setNewConfiguration(mConfiguration);
+ if (mWindowManager != null) {
+ mWindowManager.continueSurfaceLayout();
}
-
return kept;
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 022b10f..124d7f1 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -120,6 +120,7 @@
import android.widget.Toast;
import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
@@ -226,7 +227,7 @@
private VrManagerInternal mVrManagerInternal;
final IBinder mForegroundToken = new Binder();
- private WorkerHandler mHandler;
+ private Handler mHandler;
private final HandlerThread mRankingThread = new HandlerThread("ranker",
Process.THREAD_PRIORITY_BACKGROUND);
@@ -572,33 +573,9 @@
public void clearEffects() {
synchronized (mNotificationList) {
if (DBG) Slog.d(TAG, "clearEffects");
-
- // sound
- mSoundNotificationKey = null;
-
- long identity = Binder.clearCallingIdentity();
- try {
- final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
- if (player != null) {
- player.stopAsync();
- }
- } catch (RemoteException e) {
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
-
- // vibrate
- mVibrateNotificationKey = null;
- identity = Binder.clearCallingIdentity();
- try {
- mVibrator.cancel();
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
-
- // light
- mLights.clear();
- updateLightsLocked();
+ clearSoundLocked();
+ clearVibrateLocked();
+ clearLightsLocked();
}
}
@@ -658,6 +635,36 @@
}
};
+ private void clearSoundLocked() {
+ mSoundNotificationKey = null;
+ long identity = Binder.clearCallingIdentity();
+ try {
+ final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
+ if (player != null) {
+ player.stopAsync();
+ }
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ private void clearVibrateLocked() {
+ mVibrateNotificationKey = null;
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mVibrator.cancel();
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ private void clearLightsLocked() {
+ // light
+ mLights.clear();
+ updateLightsLocked();
+ }
+
private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -863,6 +870,26 @@
super(context);
}
+ @VisibleForTesting
+ void setAudioManager(AudioManager audioMananger) {
+ mAudioManager = audioMananger;
+ }
+
+ @VisibleForTesting
+ void setVibrator(Vibrator vibrator) {
+ mVibrator = vibrator;
+ }
+
+ @VisibleForTesting
+ void setSystemReady(boolean systemReady) {
+ mSystemReady = systemReady;
+ }
+
+ @VisibleForTesting
+ void setHandler(Handler handler) {
+ mHandler = handler;
+ }
+
@Override
public void onStart() {
Resources resources = getContext().getResources();
@@ -2492,12 +2519,14 @@
return false;
}
- private void buzzBeepBlinkLocked(NotificationRecord record) {
+ @VisibleForTesting
+ void buzzBeepBlinkLocked(NotificationRecord record) {
boolean buzz = false;
boolean beep = false;
boolean blink = false;
final Notification notification = record.sbn.getNotification();
+ final String key = record.getKey();
// Should this notification make noise, vibe, or use the LED?
final boolean aboveThreshold = record.getImportance() >= IMPORTANCE_DEFAULT;
@@ -2521,9 +2550,15 @@
if (disableEffects != null) {
ZenLog.traceDisableEffects(record, disableEffects);
}
+
+ // Remember if this notification already owns the notification channels.
+ boolean wasBeep = key != null && key.equals(mSoundNotificationKey);
+ boolean wasBuzz = key != null && key.equals(mVibrateNotificationKey);
+
+ // These are set inside the conditional if the notification is allowed to make noise.
+ boolean hasValidVibrate = false;
+ boolean hasValidSound = false;
if (disableEffects == null
- && (!(record.isUpdate
- && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0 ))
&& (record.getUserId() == UserHandle.USER_ALL ||
record.getUserId() == currentUser ||
mUserProfiles.isCurrentProfile(record.getUserId()))
@@ -2532,10 +2567,6 @@
&& mAudioManager != null) {
if (DBG) Slog.v(TAG, "Interrupting!");
- sendAccessibilityEvent(notification, record.sbn.getPackageName());
-
- // sound
-
// should we use the default notification sound? (indicated either by
// DEFAULT_SOUND or because notification.sound is pointing at
// Settings.System.NOTIFICATION_SOUND)
@@ -2545,8 +2576,6 @@
.equals(notification.sound);
Uri soundUri = null;
- boolean hasValidSound = false;
-
if (useDefaultSound) {
soundUri = Settings.System.DEFAULT_NOTIFICATION_URI;
@@ -2559,88 +2588,105 @@
hasValidSound = (soundUri != null);
}
- if (hasValidSound) {
- boolean looping =
- (notification.flags & Notification.FLAG_INSISTENT) != 0;
- AudioAttributes audioAttributes = audioAttributesForNotification(notification);
- mSoundNotificationKey = record.getKey();
- // do not play notifications if stream volume is 0 (typically because
- // ringer mode is silent) or if there is a user of exclusive audio focus
- if ((mAudioManager.getStreamVolume(
- AudioAttributes.toLegacyStreamType(audioAttributes)) != 0)
- && !mAudioManager.isAudioFocusExclusive()) {
- final long identity = Binder.clearCallingIdentity();
- try {
- final IRingtonePlayer player =
- mAudioManager.getRingtonePlayer();
- if (player != null) {
- if (DBG) Slog.v(TAG, "Playing sound " + soundUri
- + " with attributes " + audioAttributes);
- player.playAsync(soundUri, record.sbn.getUser(), looping,
- audioAttributes);
- beep = true;
- }
- } catch (RemoteException e) {
- } finally {
- Binder.restoreCallingIdentity(identity);
- }
- }
- }
-
- // vibrate
// Does the notification want to specify its own vibration?
final boolean hasCustomVibrate = notification.vibrate != null;
// new in 4.2: if there was supposed to be a sound and we're in vibrate
// mode, and no other vibration is specified, we fall back to vibration
final boolean convertSoundToVibration =
- !hasCustomVibrate
- && hasValidSound
- && (mAudioManager.getRingerModeInternal()
- == AudioManager.RINGER_MODE_VIBRATE);
+ !hasCustomVibrate
+ && hasValidSound
+ && (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_VIBRATE);
// The DEFAULT_VIBRATE flag trumps any custom vibration AND the fallback.
final boolean useDefaultVibrate =
(notification.defaults & Notification.DEFAULT_VIBRATE) != 0;
- if ((useDefaultVibrate || convertSoundToVibration || hasCustomVibrate)
- && !(mAudioManager.getRingerModeInternal()
- == AudioManager.RINGER_MODE_SILENT)) {
- mVibrateNotificationKey = record.getKey();
+ hasValidVibrate = useDefaultVibrate || convertSoundToVibration ||
+ hasCustomVibrate;
- if (useDefaultVibrate || convertSoundToVibration) {
- // Escalate privileges so we can use the vibrator even if the
- // notifying app does not have the VIBRATE permission.
- long identity = Binder.clearCallingIdentity();
- try {
- mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
- useDefaultVibrate ? mDefaultVibrationPattern
- : mFallbackVibrationPattern,
- ((notification.flags & Notification.FLAG_INSISTENT) != 0)
- ? 0: -1, audioAttributesForNotification(notification));
- buzz = true;
- } finally {
- Binder.restoreCallingIdentity(identity);
+ // We can alert, and we're allowed to alert, but if the developer asked us to only do
+ // it once, and we already have, then don't.
+ if (!(record.isUpdate
+ && (notification.flags & Notification.FLAG_ONLY_ALERT_ONCE) != 0)) {
+
+ sendAccessibilityEvent(notification, record.sbn.getPackageName());
+
+ if (hasValidSound) {
+ boolean looping =
+ (notification.flags & Notification.FLAG_INSISTENT) != 0;
+ AudioAttributes audioAttributes = audioAttributesForNotification(notification);
+ mSoundNotificationKey = key;
+ // do not play notifications if stream volume is 0 (typically because
+ // ringer mode is silent) or if there is a user of exclusive audio focus
+ if ((mAudioManager.getStreamVolume(
+ AudioAttributes.toLegacyStreamType(audioAttributes)) != 0)
+ && !mAudioManager.isAudioFocusExclusive()) {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final IRingtonePlayer player =
+ mAudioManager.getRingtonePlayer();
+ if (player != null) {
+ if (DBG) Slog.v(TAG, "Playing sound " + soundUri
+ + " with attributes " + audioAttributes);
+ player.playAsync(soundUri, record.sbn.getUser(), looping,
+ audioAttributes);
+ beep = true;
+ }
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
- } else if (notification.vibrate.length > 1) {
- // If you want your own vibration pattern, you need the VIBRATE
- // permission
- mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
- notification.vibrate,
- ((notification.flags & Notification.FLAG_INSISTENT) != 0)
- ? 0: -1, audioAttributesForNotification(notification));
- buzz = true;
+ }
+
+ if (hasValidVibrate && !(mAudioManager.getRingerModeInternal()
+ == AudioManager.RINGER_MODE_SILENT)) {
+ mVibrateNotificationKey = key;
+
+ if (useDefaultVibrate || convertSoundToVibration) {
+ // Escalate privileges so we can use the vibrator even if the
+ // notifying app does not have the VIBRATE permission.
+ long identity = Binder.clearCallingIdentity();
+ try {
+ mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
+ useDefaultVibrate ? mDefaultVibrationPattern
+ : mFallbackVibrationPattern,
+ ((notification.flags & Notification.FLAG_INSISTENT) != 0)
+ ? 0: -1, audioAttributesForNotification(notification));
+ buzz = true;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ } else if (notification.vibrate.length > 1) {
+ // If you want your own vibration pattern, you need the VIBRATE
+ // permission
+ mVibrator.vibrate(record.sbn.getUid(), record.sbn.getOpPkg(),
+ notification.vibrate,
+ ((notification.flags & Notification.FLAG_INSISTENT) != 0)
+ ? 0: -1, audioAttributesForNotification(notification));
+ buzz = true;
+ }
}
}
+
+ }
+ // If a notification is updated to remove the actively playing sound or vibrate,
+ // cancel that feedback now
+ if (wasBeep && !hasValidSound) {
+ clearSoundLocked();
+ }
+ if (wasBuzz && !hasValidVibrate) {
+ clearVibrateLocked();
}
// light
// release the light
- boolean wasShowLights = mLights.remove(record.getKey());
+ boolean wasShowLights = mLights.remove(key);
if ((notification.flags & Notification.FLAG_SHOW_LIGHTS) != 0 && aboveThreshold
&& ((record.getSuppressedVisualEffects()
& NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF) == 0)) {
- mLights.add(record.getKey());
+ mLights.add(key);
updateLightsLocked();
if (mUseAttentionLight) {
mAttentionLight.pulse();
@@ -2654,7 +2700,7 @@
& NotificationListenerService.SUPPRESSED_EFFECT_SCREEN_OFF) != 0)) {
if (DBG) Slog.v(TAG, "Suppressed SystemUI from triggering screen on");
} else {
- EventLogTags.writeNotificationAlert(record.getKey(),
+ EventLogTags.writeNotificationAlert(key,
buzz ? 1 : 0, beep ? 1 : 0, blink ? 1 : 0);
mHandler.post(mBuzzBeepBlinked);
}
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 0bf7102..bb0ec4c 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -128,6 +128,10 @@
// in which case a second window animation would cause jitter.
private boolean mFreezeMovementAnimations = false;
+ // Temporary storage for the new bounds that should be used after the configuration change.
+ // Will be cleared once the client retrieves the new bounds via getBoundsForNewConfiguration().
+ private final Rect mBoundsAfterRotation = new Rect();
+
TaskStack(WindowManagerService service, int stackId) {
mService = service;
mStackId = stackId;
@@ -343,28 +347,28 @@
setBounds(mTmpRect2);
} else {
mLastUpdateDisplayInfoRotation = newRotation;
- updateBoundsAfterRotation();
+ updateBoundsAfterRotation(true);
}
}
- void onConfigurationChanged() {
+ boolean onConfigurationChanged() {
mLastConfigChangedRotation = getDisplayInfo().rotation;
- updateBoundsAfterRotation();
+ return updateBoundsAfterRotation(false);
}
- void updateBoundsAfterRotation() {
+ boolean updateBoundsAfterRotation(boolean scheduleResize) {
if (mLastConfigChangedRotation != mLastUpdateDisplayInfoRotation) {
// We wait for the rotation values after configuration change and display info. update
// to be equal before updating the bounds due to rotation change otherwise things might
// get out of alignment...
- return;
+ return false;
}
final int newRotation = getDisplayInfo().rotation;
if (mRotation == newRotation) {
// Nothing to do here if the rotation didn't change
- return;
+ return false;
}
mDisplayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
@@ -373,11 +377,22 @@
snapDockedStackAfterRotation(mTmpRect2);
}
- // Post message to inform activity manager of the bounds change simulating
- // a one-way call. We do this to prevent a deadlock between window manager
- // lock and activity manager lock been held.
- mService.mH.obtainMessage(
- RESIZE_STACK, mStackId, 0 /*allowResizeInDockedMode*/, mTmpRect2).sendToTarget();
+ if (scheduleResize) {
+ // Post message to inform activity manager of the bounds change simulating
+ // a one-way call. We do this to prevent a deadlock between window manager
+ // lock and activity manager lock been held.
+ mService.mH.obtainMessage(RESIZE_STACK, mStackId,
+ 0 /*allowResizeInDockedMode*/, mTmpRect2).sendToTarget();
+ } else {
+ mBoundsAfterRotation.set(mTmpRect2);
+ }
+
+ return true;
+ }
+
+ void getBoundsForNewConfiguration(Rect outBounds) {
+ outBounds.set(mBoundsAfterRotation);
+ mBoundsAfterRotation.setEmpty();
}
/**
@@ -869,6 +884,10 @@
}
}
+ boolean isAdjustedForMinimizedDock() {
+ return mMinimizeAmount != 0f;
+ }
+
private boolean adjustForIME(final WindowState imeWin) {
final int dockedSide = getDockSide();
final boolean dockedTopOrBottom = dockedSide == DOCKED_TOP || dockedSide == DOCKED_BOTTOM;
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index dcb4a63..14ae74f 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -125,6 +125,7 @@
import com.android.internal.app.IAssistScreenshotReceiver;
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IShortcutService;
+import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
@@ -515,6 +516,8 @@
private final SparseIntArray mTmpTaskIds = new SparseIntArray();
+ private final ArrayList<Integer> mChangedStackList = new ArrayList();
+
boolean mForceResizableTasks = false;
int getDragLayerLocked() {
@@ -3398,7 +3401,8 @@
}
}
- if (isStackVisibleLocked(DOCKED_STACK_ID)
+ if ((isStackVisibleLocked(DOCKED_STACK_ID)
+ && !mStackIdToStack.get(DOCKED_STACK_ID).isAdjustedForMinimizedDock())
|| isStackVisibleLocked(FREEFORM_WORKSPACE_STACK_ID)) {
// We don't let app affect the system orientation when in freeform or docked mode since
// they don't occupy the entire display and their request can conflict with other apps.
@@ -3580,7 +3584,7 @@
}
@Override
- public void setNewConfiguration(Configuration config) {
+ public int[] setNewConfiguration(Configuration config) {
if (!checkCallingPermission(android.Manifest.permission.MANAGE_APP_TOKENS,
"setNewConfiguration()")) {
throw new SecurityException("Requires MANAGE_APP_TOKENS permission");
@@ -3592,16 +3596,30 @@
mWaitingForConfig = false;
mLastFinishedFreezeSource = "new-config";
}
- onConfigurationChanged();
- mWindowPlacerLocked.performSurfacePlacement();
+ return onConfigurationChanged();
}
}
- private void onConfigurationChanged() {
+ @Override
+ public Rect getBoundsForNewConfiguration(int stackId) {
+ synchronized(mWindowMap) {
+ final TaskStack stack = mStackIdToStack.get(stackId);
+ final Rect outBounds = new Rect();
+ stack.getBoundsForNewConfiguration(outBounds);
+ return outBounds;
+ }
+ }
+
+ private int[] onConfigurationChanged() {
+ mChangedStackList.clear();
for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; stackNdx--) {
final TaskStack stack = mStackIdToStack.valueAt(stackNdx);
- stack.onConfigurationChanged();
+ if (stack.onConfigurationChanged()) {
+ mChangedStackList.add(stack.mStackId);
+ }
}
+ return mChangedStackList.isEmpty() ?
+ null : ArrayUtils.convertToIntArray(mChangedStackList);
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java b/services/tests/servicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
new file mode 100644
index 0000000..83a59fd
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/notification/BuzzBeepBlinkTest.java
@@ -0,0 +1,541 @@
+/*
+ * 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.server.notification;
+
+
+import android.app.ActivityManager;
+import android.app.Notification;
+import android.app.Notification.Builder;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.os.Vibrator;
+import android.service.notification.NotificationListenerService.Ranking;
+import android.service.notification.StatusBarNotification;
+import android.test.AndroidTestCase;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyObject;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+public class BuzzBeepBlinkTest extends AndroidTestCase {
+
+ @Mock AudioManager mAudioManager;
+ @Mock Vibrator mVibrator;
+ @Mock android.media.IRingtonePlayer mRingtonePlayer;
+ @Mock Handler mHandler;
+
+ private NotificationManagerService mService;
+ private String mPkg = "com.android.server.notification";
+ private int mId = 1001;
+ private int mOtherId = 1002;
+ private String mTag = null;
+ private int mUid = 1000;
+ private int mPid = 2000;
+ private int mScore = 10;
+ private android.os.UserHandle mUser = UserHandle.of(ActivityManager.getCurrentUser());
+
+ @Override
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ when(mAudioManager.isAudioFocusExclusive()).thenReturn(false);
+ when(mAudioManager.getRingtonePlayer()).thenReturn(mRingtonePlayer);
+ when(mAudioManager.getStreamVolume(anyInt())).thenReturn(10);
+ when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_NORMAL);
+
+ mService = new NotificationManagerService(getContext());
+ mService.setAudioManager(mAudioManager);
+ mService.setVibrator(mVibrator);
+ mService.setSystemReady(true);
+ mService.setHandler(mHandler);
+ }
+
+ //
+ // Convenience functions for creating notification records
+ //
+
+ private NotificationRecord getNoisyOtherNotification() {
+ return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
+ true /* noisy */, true /* buzzy*/);
+ }
+
+ private NotificationRecord getBeepyNotification() {
+ return getNotificationRecord(mId, false /* insistent */, false /* once */,
+ true /* noisy */, false /* buzzy*/);
+ }
+
+ private NotificationRecord getBeepyOnceNotification() {
+ return getNotificationRecord(mId, false /* insistent */, true /* once */,
+ true /* noisy */, false /* buzzy*/);
+ }
+
+ private NotificationRecord getQuietNotification() {
+ return getNotificationRecord(mId, false /* insistent */, false /* once */,
+ false /* noisy */, false /* buzzy*/);
+ }
+
+ private NotificationRecord getQuietOtherNotification() {
+ return getNotificationRecord(mOtherId, false /* insistent */, false /* once */,
+ false /* noisy */, false /* buzzy*/);
+ }
+
+ private NotificationRecord getQuietOnceNotification() {
+ return getNotificationRecord(mId, false /* insistent */, true /* once */,
+ false /* noisy */, false /* buzzy*/);
+ }
+
+ private NotificationRecord getInsistentBeepyNotification() {
+ return getNotificationRecord(mId, true /* insistent */, false /* once */,
+ true /* noisy */, false /* buzzy*/);
+ }
+
+ private NotificationRecord getBuzzyNotification() {
+ return getNotificationRecord(mId, false /* insistent */, false /* once */,
+ false /* noisy */, true /* buzzy*/);
+ }
+
+ private NotificationRecord getBuzzyOnceNotification() {
+ return getNotificationRecord(mId, false /* insistent */, true /* once */,
+ false /* noisy */, true /* buzzy*/);
+ }
+
+ private NotificationRecord getInsistentBuzzyNotification() {
+ return getNotificationRecord(mId, true /* insistent */, false /* once */,
+ false /* noisy */, true /* buzzy*/);
+ }
+
+ private NotificationRecord getNotificationRecord(int id, boolean insistent, boolean once,
+ boolean noisy, boolean buzzy) {
+ final Builder builder = new Builder(getContext())
+ .setContentTitle("foo")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .setPriority(Notification.PRIORITY_HIGH)
+ .setOnlyAlertOnce(once);
+
+ int defaults = 0;
+ if (noisy) {
+ defaults |= Notification.DEFAULT_SOUND;
+ }
+ if (buzzy) {
+ defaults |= Notification.DEFAULT_VIBRATE;
+ }
+ builder.setDefaults(defaults);
+
+ Notification n = builder.build();
+ if (insistent) {
+ n.flags |= Notification.FLAG_INSISTENT;
+ }
+ StatusBarNotification sbn = new StatusBarNotification(mPkg, mPkg, id, mTag, mUid, mPid,
+ mScore, n, mUser, System.currentTimeMillis());
+ return new NotificationRecord(getContext(), sbn);
+ }
+
+ //
+ // Convenience functions for interacting with mocks
+ //
+
+ private void verifyNeverBeep() throws RemoteException {
+ verify(mRingtonePlayer, never()).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
+ anyBoolean(), (AudioAttributes) anyObject());
+ }
+
+ private void verifyBeep() throws RemoteException {
+ verify(mRingtonePlayer, times(1)).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
+ eq(true), (AudioAttributes) anyObject());
+ }
+
+ private void verifyBeepLooped() throws RemoteException {
+ verify(mRingtonePlayer, times(1)).playAsync((Uri) anyObject(), (UserHandle) anyObject(),
+ eq(false), (AudioAttributes) anyObject());
+ }
+
+ private void verifyNeverStopAudio() throws RemoteException {
+ verify(mRingtonePlayer, never()).stopAsync();
+ }
+
+ private void verifyStopAudio() throws RemoteException {
+ verify(mRingtonePlayer, times(1)).stopAsync();
+ }
+
+ private void verifyNeverVibrate() {
+ verify(mVibrator, never()).vibrate(anyInt(), anyString(), (long[]) anyObject(),
+ anyInt(), (AudioAttributes) anyObject());
+ }
+
+ private void verifyVibrate() {
+ verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), (long[]) anyObject(),
+ eq(-1), (AudioAttributes) anyObject());
+ }
+
+ private void verifyVibrateLooped() {
+ verify(mVibrator, times(1)).vibrate(anyInt(), anyString(), (long[]) anyObject(),
+ eq(0), (AudioAttributes) anyObject());
+ }
+
+ private void verifyStopVibrate() {
+ verify(mVibrator, times(1)).cancel();
+ }
+
+ private void verifyNeverStopVibrate() throws RemoteException {
+ verify(mVibrator, never()).cancel();
+ }
+
+ @SmallTest
+ public void testBeep() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyBeepLooped();
+ verifyNeverVibrate();
+ }
+
+ //
+ // Tests
+ //
+
+ @SmallTest
+ public void testBeepInsistently() throws Exception {
+ NotificationRecord r = getInsistentBeepyNotification();
+
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyBeep();
+ }
+
+ @SmallTest
+ public void testNoInterruptionForMin() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ r.setImportance(Ranking.IMPORTANCE_MIN, "foo");
+
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyNeverBeep();
+ verifyNeverVibrate();
+ }
+
+ @SmallTest
+ public void testNoInterruptionForIntercepted() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ r.setIntercepted(true);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyNeverBeep();
+ verifyNeverVibrate();
+ }
+
+ @SmallTest
+ public void testBeepTwice() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ Mockito.reset(mRingtonePlayer);
+
+ // update should beep
+ r.isUpdate = true;
+ mService.buzzBeepBlinkLocked(r);
+ verifyBeepLooped();
+ }
+
+ @SmallTest
+ public void testHonorAlertOnlyOnceForBeep() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ NotificationRecord s = getBeepyOnceNotification();
+ s.isUpdate = true;
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ Mockito.reset(mRingtonePlayer);
+
+ // update should not beep
+ mService.buzzBeepBlinkLocked(s);
+ verifyNeverBeep();
+ }
+
+ @SmallTest
+ public void testNoisyUpdateDoesNotCancelAudio() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+
+ mService.buzzBeepBlinkLocked(r);
+ r.isUpdate = true;
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyNeverStopAudio();
+ }
+
+ @SmallTest
+ public void testNoisyOnceUpdateDoesNotCancelAudio() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ NotificationRecord s = getBeepyOnceNotification();
+ s.isUpdate = true;
+
+ mService.buzzBeepBlinkLocked(r);
+ mService.buzzBeepBlinkLocked(s);
+
+ verifyNeverStopAudio();
+ }
+
+ @SmallTest
+ public void testQuietUpdateDoesNotCancelAudioFromOther() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ NotificationRecord s = getQuietNotification();
+ s.isUpdate = true;
+ NotificationRecord other = getNoisyOtherNotification();
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ mService.buzzBeepBlinkLocked(other); // this takes the audio stream
+ Mockito.reset(mRingtonePlayer);
+
+ // should not stop noise, since we no longer own it
+ mService.buzzBeepBlinkLocked(s); // this no longer owns the stream
+ verifyNeverStopAudio();
+ }
+
+ @SmallTest
+ public void testQuietInterloperDoesNotCancelAudio() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ NotificationRecord other = getQuietOtherNotification();
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ Mockito.reset(mRingtonePlayer);
+
+ // should not stop noise, since it does not own it
+ mService.buzzBeepBlinkLocked(other);
+ verifyNeverStopAudio();
+ }
+
+ @SmallTest
+ public void testQuietUpdateCancelsAudio() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ NotificationRecord s = getQuietNotification();
+ s.isUpdate = true;
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ Mockito.reset(mRingtonePlayer);
+
+ // quiet update should stop making noise
+ mService.buzzBeepBlinkLocked(s);
+ verifyStopAudio();
+ }
+
+ @SmallTest
+ public void testQuietOnceUpdateCancelsAudio() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ NotificationRecord s = getQuietOnceNotification();
+ s.isUpdate = true;
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ Mockito.reset(mRingtonePlayer);
+
+ // stop making noise - this is a weird corner case, but quiet should override once
+ mService.buzzBeepBlinkLocked(s);
+ verifyStopAudio();
+ }
+
+ @SmallTest
+ public void testDemoteSoundToVibrate() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+
+ // the phone is quiet
+ when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+ when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyNeverBeep();
+ verifyVibrate();
+ }
+
+ @SmallTest
+ public void testDemotInsistenteSoundToVibrate() throws Exception {
+ NotificationRecord r = getInsistentBeepyNotification();
+
+ // the phone is quiet
+ when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+ when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyVibrateLooped();
+ }
+
+ @SmallTest
+ public void testVibrate() throws Exception {
+ NotificationRecord r = getBuzzyNotification();
+
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyNeverBeep();
+ verifyVibrate();
+ }
+
+ @SmallTest
+ public void testInsistenteVibrate() throws Exception {
+ NotificationRecord r = getInsistentBuzzyNotification();
+
+ mService.buzzBeepBlinkLocked(r);
+ verifyVibrateLooped();
+ }
+
+ @SmallTest
+ public void testVibratTwice() throws Exception {
+ NotificationRecord r = getBuzzyNotification();
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ Mockito.reset(mVibrator);
+
+ // update should vibrate
+ r.isUpdate = true;
+ mService.buzzBeepBlinkLocked(r);
+ verifyVibrate();
+ }
+
+ @SmallTest
+ public void testHonorAlertOnlyOnceForBuzz() throws Exception {
+ NotificationRecord r = getBuzzyNotification();
+ NotificationRecord s = getBuzzyOnceNotification();
+ s.isUpdate = true;
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ Mockito.reset(mVibrator);
+
+ // update should not beep
+ mService.buzzBeepBlinkLocked(s);
+ verifyNeverVibrate();
+ }
+
+ @SmallTest
+ public void testNoisyUpdateDoesNotCancelVibrate() throws Exception {
+ NotificationRecord r = getBuzzyNotification();
+
+ mService.buzzBeepBlinkLocked(r);
+ r.isUpdate = true;
+ mService.buzzBeepBlinkLocked(r);
+
+ verifyNeverStopVibrate();
+ }
+
+ @SmallTest
+ public void testNoisyOnceUpdateDoesNotCancelVibrate() throws Exception {
+ NotificationRecord r = getBuzzyNotification();
+ NotificationRecord s = getBuzzyOnceNotification();
+ s.isUpdate = true;
+
+ mService.buzzBeepBlinkLocked(r);
+ mService.buzzBeepBlinkLocked(s);
+
+ verifyNeverStopVibrate();
+ }
+
+ @SmallTest
+ public void testQuietUpdateDoesNotCancelVibrateFromOther() throws Exception {
+ NotificationRecord r = getBuzzyNotification();
+ NotificationRecord s = getQuietNotification();
+ s.isUpdate = true;
+ NotificationRecord other = getNoisyOtherNotification();
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ mService.buzzBeepBlinkLocked(other); // this takes the vibrate stream
+ Mockito.reset(mVibrator);
+
+ // should not stop vibrate, since we no longer own it
+ mService.buzzBeepBlinkLocked(s); // this no longer owns the stream
+ verifyNeverStopVibrate();
+ }
+
+ @SmallTest
+ public void testQuietInterloperDoesNotCancelVibrate() throws Exception {
+ NotificationRecord r = getBuzzyNotification();
+ NotificationRecord other = getQuietOtherNotification();
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ Mockito.reset(mVibrator);
+
+ // should not stop noise, since it does not own it
+ mService.buzzBeepBlinkLocked(other);
+ verifyNeverStopVibrate();
+ }
+
+ @SmallTest
+ public void testQuietUpdateCancelsVibrate() throws Exception {
+ NotificationRecord r = getBuzzyNotification();
+ NotificationRecord s = getQuietNotification();
+ s.isUpdate = true;
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+
+ // quiet update should stop making noise
+ mService.buzzBeepBlinkLocked(s);
+ verifyStopVibrate();
+ }
+
+ @SmallTest
+ public void testQuietOnceUpdateCancelsvibrate() throws Exception {
+ NotificationRecord r = getBuzzyNotification();
+ NotificationRecord s = getQuietOnceNotification();
+ s.isUpdate = true;
+
+ // set up internal state
+ mService.buzzBeepBlinkLocked(r);
+ Mockito.reset(mVibrator);
+
+ // stop making noise - this is a weird corner case, but quiet should override once
+ mService.buzzBeepBlinkLocked(s);
+ verifyStopVibrate();
+ }
+
+ @SmallTest
+ public void testQuietUpdateCancelsDemotedVibrate() throws Exception {
+ NotificationRecord r = getBeepyNotification();
+ NotificationRecord s = getQuietNotification();
+
+ // the phone is quiet
+ when(mAudioManager.getStreamVolume(anyInt())).thenReturn(0);
+ when(mAudioManager.getRingerModeInternal()).thenReturn(AudioManager.RINGER_MODE_VIBRATE);
+
+ mService.buzzBeepBlinkLocked(r);
+
+ // quiet update should stop making noise
+ mService.buzzBeepBlinkLocked(s);
+ verifyStopVibrate();
+ }
+}
diff --git a/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java b/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java
index ad02d2b..c0583ce 100644
--- a/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java
+++ b/tests/SoundTriggerTests/src/android/hardware/soundtrigger/stubhal/GenericSoundModelTest.java
@@ -18,6 +18,7 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;
@@ -40,6 +41,7 @@
import java.net.InetAddress;
import java.net.Socket;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.Random;
import java.util.UUID;
@@ -53,7 +55,7 @@
static final int MSG_GENERIC_TRIGGER = 4;
private Random random = new Random();
- private ArrayList<UUID> loadedModelUuids;
+ private HashSet<UUID> loadedModelUuids;
private ISoundTriggerService soundTriggerService;
private SoundTriggerManager soundTriggerManager;
@@ -68,7 +70,7 @@
soundTriggerManager = (SoundTriggerManager) context.getSystemService(
Context.SOUND_TRIGGER_SERVICE);
- loadedModelUuids = new ArrayList<UUID>();
+ loadedModelUuids = new HashSet<UUID>();
}
@Override
@@ -170,6 +172,101 @@
verify(spyCallback, timeout(100)).onGenericSoundTriggerDetected(any());
}
+ /**
+ * Tests a more complicated pattern of loading, unloading, triggering, starting and stopping
+ * recognition. Intended to find unexpected errors that occur in unexpected states.
+ */
+ @LargeTest
+ public void testFuzzGenericSoundModel() throws Exception {
+ int numModels = 2;
+
+ final int STATUS_UNLOADED = 0;
+ final int STATUS_LOADED = 1;
+ final int STATUS_STARTED = 2;
+
+ class ModelInfo {
+ int status;
+ GenericSoundModel model;
+
+ public ModelInfo(GenericSoundModel model, int status) {
+ this.status = status;
+ this.model = model;
+ }
+ }
+
+ Random predictableRandom = new Random(100);
+
+ ArrayList modelInfos = new ArrayList<ModelInfo>();
+ for(int i=0; i<numModels; i++) {
+ // Create sound model
+ byte[] data = new byte[1024];
+ predictableRandom.nextBytes(data);
+ UUID modelUuid = UUID.randomUUID();
+ UUID mVendorUuid = UUID.randomUUID();
+ GenericSoundModel model = new GenericSoundModel(modelUuid, mVendorUuid, data);
+ ModelInfo modelInfo = new ModelInfo(model, STATUS_UNLOADED);
+ modelInfos.add(modelInfo);
+ }
+
+ boolean captureTriggerAudio = true;
+ boolean allowMultipleTriggers = true;
+ RecognitionConfig config = new RecognitionConfig(captureTriggerAudio, allowMultipleTriggers,
+ null, null);
+ TestRecognitionStatusCallback spyCallback = spy(new TestRecognitionStatusCallback());
+
+
+ int numOperationsToRun = 100;
+ for(int i=0; i<numOperationsToRun; i++) {
+ // Select a random model
+ int modelInfoIndex = predictableRandom.nextInt(modelInfos.size());
+ ModelInfo modelInfo = (ModelInfo) modelInfos.get(modelInfoIndex);
+
+ // Perform a random operation
+ int operation = predictableRandom.nextInt(5);
+
+ if (operation == 0 && modelInfo.status == STATUS_UNLOADED) {
+ // Update and start sound model
+ soundTriggerService.updateSoundModel(modelInfo.model);
+ loadedModelUuids.add(modelInfo.model.uuid);
+ modelInfo.status = STATUS_LOADED;
+ } else if (operation == 1 && modelInfo.status == STATUS_LOADED) {
+ // Start the sound model
+ int r = soundTriggerService.startRecognition(new ParcelUuid(modelInfo.model.uuid),
+ spyCallback, config);
+ assertEquals("Could Not Start Recognition with code: " + r,
+ android.hardware.soundtrigger.SoundTrigger.STATUS_OK, r);
+ modelInfo.status = STATUS_STARTED;
+ } else if (operation == 2 && modelInfo.status == STATUS_STARTED) {
+ // Send trigger to stub HAL
+ Socket socket = new Socket(InetAddress.getLocalHost(), 14035);
+ DataOutputStream out = new DataOutputStream(socket.getOutputStream());
+ out.writeBytes("trig " + modelInfo.model.uuid + "\r\n");
+ out.flush();
+ socket.close();
+
+ // Verify trigger was received
+ verify(spyCallback, timeout(100)).onGenericSoundTriggerDetected(any());
+ reset(spyCallback);
+ } else if (operation == 3 && modelInfo.status == STATUS_STARTED) {
+ // Stop recognition
+ int r = soundTriggerService.stopRecognition(new ParcelUuid(modelInfo.model.uuid),
+ spyCallback);
+ assertEquals("Could Not Stop Recognition with code: " + r,
+ android.hardware.soundtrigger.SoundTrigger.STATUS_OK, r);
+ modelInfo.status = STATUS_LOADED;
+ } else if (operation == 4 && modelInfo.status != STATUS_UNLOADED) {
+ // Delete sound model
+ soundTriggerService.deleteSoundModel(new ParcelUuid(modelInfo.model.uuid));
+ loadedModelUuids.remove(modelInfo.model.uuid);
+
+ // Confirm it was deleted
+ GenericSoundModel returnedModel =
+ soundTriggerService.getSoundModel(new ParcelUuid(modelInfo.model.uuid));
+ assertEquals(null, returnedModel);
+ modelInfo.status = STATUS_UNLOADED;
+ }
+ }
+ }
public class TestRecognitionStatusCallback extends IRecognitionStatusCallback.Stub {
@Override
diff --git a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
index 7faee1b..f9e008e 100644
--- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
+++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java
@@ -403,8 +403,15 @@
}
@Override
- public void setNewConfiguration(Configuration arg0) throws RemoteException {
+ public int[] setNewConfiguration(Configuration arg0) throws RemoteException {
// TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Rect getBoundsForNewConfiguration(int stackId) throws RemoteException {
+ // TODO Auto-generated method stub
+ return null;
}
@Override