diff options
27 files changed, 327 insertions, 283 deletions
diff --git a/api/current.txt b/api/current.txt index 7d8b892fa151..a1cdc8d5aa21 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1711,6 +1711,7 @@ package android { field public static final int paste = 16908322; // 0x1020022 field public static final int primary = 16908300; // 0x102000c field public static final int progress = 16908301; // 0x102000d + field public static final int redo = 16908338; // 0x1020032 field public static final int secondaryProgress = 16908303; // 0x102000f field public static final int selectAll = 16908319; // 0x102001f field public static final int selectTextMode = 16908333; // 0x102002d @@ -1727,6 +1728,7 @@ package android { field public static final int text2 = 16908309; // 0x1020015 field public static final int title = 16908310; // 0x1020016 field public static final int toggle = 16908311; // 0x1020017 + field public static final int undo = 16908337; // 0x1020031 field public static final int widget_frame = 16908312; // 0x1020018 } @@ -28745,6 +28747,7 @@ package android.telecom { method public boolean isInCall(); method public void showInCallScreen(boolean); field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS"; + field public static final java.lang.String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS"; field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ',' field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';' field public static final java.lang.String EXTRA_CALL_DISCONNECT_CAUSE = "android.telecom.extra.CALL_DISCONNECT_CAUSE"; diff --git a/api/system-current.txt b/api/system-current.txt index 696889653e17..13a8981c86c8 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -1787,6 +1787,7 @@ package android { field public static final int paste = 16908322; // 0x1020022 field public static final int primary = 16908300; // 0x102000c field public static final int progress = 16908301; // 0x102000d + field public static final int redo = 16908338; // 0x1020032 field public static final int secondaryProgress = 16908303; // 0x102000f field public static final int selectAll = 16908319; // 0x102001f field public static final int selectTextMode = 16908333; // 0x102002d @@ -1803,6 +1804,7 @@ package android { field public static final int text2 = 16908309; // 0x1020015 field public static final int title = 16908310; // 0x1020016 field public static final int toggle = 16908311; // 0x1020017 + field public static final int undo = 16908337; // 0x1020031 field public static final int widget_frame = 16908312; // 0x1020018 } @@ -15118,6 +15120,8 @@ package android.media { field public static final android.os.Parcelable.Creator<android.media.AudioAttributes> CREATOR; field public static final int FLAG_AUDIBILITY_ENFORCED = 1; // 0x1 field public static final int FLAG_BEACON = 8; // 0x8 + field public static final int FLAG_BYPASS_INTERRUPTION_POLICY = 64; // 0x40 + field public static final int FLAG_BYPASS_MUTE = 128; // 0x80 field public static final int FLAG_HW_AV_SYNC = 16; // 0x10 field public static final int FLAG_HW_HOTWORD = 32; // 0x20 field public static final int USAGE_ALARM = 4; // 0x4 @@ -30863,6 +30867,7 @@ package android.telecom { field public static final java.lang.String ACTION_CHANGE_PHONE_ACCOUNTS = "android.telecom.action.CHANGE_PHONE_ACCOUNTS"; field public static final java.lang.String ACTION_CONNECTION_SERVICE_CONFIGURE = "android.telecom.action.CONNECTION_SERVICE_CONFIGURE"; field public static final java.lang.String ACTION_SHOW_CALL_SETTINGS = "android.telecom.action.SHOW_CALL_SETTINGS"; + field public static final java.lang.String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS"; field public static final char DTMF_CHARACTER_PAUSE = 44; // 0x002c ',' field public static final char DTMF_CHARACTER_WAIT = 59; // 0x003b ';' field public static final java.lang.String EXTRA_CALL_BACK_NUMBER = "android.telecom.extra.CALL_BACK_NUMBER"; diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index c3dd4cec72ff..30da0e7652a5 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.ContentObserver; +import android.media.AudioAttributes; import android.media.AudioManager; import android.media.Ringtone; import android.media.RingtoneManager; @@ -174,6 +175,11 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba } if (mRingtone != null) { try { + mRingtone.setAudioAttributes(new AudioAttributes.Builder(mRingtone + .getAudioAttributes()) + .setFlags(AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY | + AudioAttributes.FLAG_BYPASS_MUTE) + .build()); mRingtone.play(); } catch (Throwable e) { Log.w(TAG, "Error playing ringtone, stream " + mStreamType, e); diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 4752594e06dd..8601d2b67b9d 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -50,6 +50,7 @@ import android.graphics.drawable.Drawable; import android.inputmethodservice.ExtractEditText; import android.os.Bundle; import android.os.Handler; +import android.os.ParcelableParcel; import android.os.SystemClock; import android.provider.Settings; import android.text.DynamicLayout; @@ -118,15 +119,18 @@ import java.util.HashMap; */ public class Editor { private static final String TAG = "Editor"; - static final boolean DEBUG_UNDO = false; + private static final boolean DEBUG_UNDO = false; static final int BLINK = 500; private static final float[] TEMP_POSITION = new float[2]; private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20; + // Tag used when the Editor maintains its own separate UndoManager. + private static final String UNDO_OWNER_TAG = "Editor"; - UndoManager mUndoManager; - UndoOwner mUndoOwner; - InputFilter mUndoInputFilter; + // Each Editor manages its own undo stack. + private final UndoManager mUndoManager = new UndoManager(); + private UndoOwner mUndoOwner = mUndoManager.getOwner(UNDO_OWNER_TAG, this); + final InputFilter mUndoInputFilter = new UndoInputFilter(this); // Cursor Controllers. InsertionPointCursorController mInsertionPointCursorController; @@ -222,6 +226,39 @@ public class Editor { Editor(TextView textView) { mTextView = textView; + // Synchronize the filter list, which places the undo input filter at the end. + mTextView.setFilters(mTextView.getFilters()); + } + + ParcelableParcel saveInstanceState() { + // For now there is only undo state. + return (ParcelableParcel) mUndoManager.saveInstanceState(); + } + + void restoreInstanceState(ParcelableParcel state) { + mUndoManager.restoreInstanceState(state); + // Re-associate this object as the owner of undo state. + mUndoOwner = mUndoManager.getOwner(UNDO_OWNER_TAG, this); + } + + boolean canUndo() { + UndoOwner[] owners = { mUndoOwner }; + return mUndoManager.countUndos(owners) > 0; + } + + boolean canRedo() { + UndoOwner[] owners = { mUndoOwner }; + return mUndoManager.countRedos(owners) > 0; + } + + void undo() { + UndoOwner[] owners = { mUndoOwner }; + mUndoManager.undo(owners, 1); // Undo 1 action. + } + + void redo() { + UndoOwner[] owners = { mUndoOwner }; + mUndoManager.redo(owners, 1); // Redo 1 action. } void onAttachedToWindow() { @@ -1706,7 +1743,7 @@ public class Editor { /** * Called by the framework in response to a text auto-correction (such as fixing a typo using a - * a dictionnary) from the current input method, provided by it calling + * a dictionary) from the current input method, provided by it calling * {@link InputConnection#commitCorrection} InputConnection.commitCorrection()}. The default * implementation flashes the background of the corrected word to provide feedback to the user. * @@ -4161,8 +4198,12 @@ public class Editor { int mChangedStart, mChangedEnd, mChangedDelta; } + /** + * An InputFilter that monitors text input to maintain undo history. It does not modify the + * text being typed (and hence always returns null from the filter() method). + */ public static class UndoInputFilter implements InputFilter { - final Editor mEditor; + private final Editor mEditor; public UndoInputFilter(Editor editor) { mEditor = editor; @@ -4192,6 +4233,8 @@ public class Editor { // The current operation is an add... are we adding more? We are adding // more if we are either appending new text to the end of the last edit or // completely replacing some or all of the last edit. + // TODO: This sequence doesn't work right: a, left-arrow, b, undo, undo. + // The two edits are incorrectly merged, so there is only one undo available. if (start < end && ((dstart >= op.mRangeStart && dend <= op.mRangeEnd) || (dstart == op.mRangeEnd && dend == op.mRangeEnd))) { op.mRangeEnd = dstart + (end-start); @@ -4245,7 +4288,10 @@ public class Editor { } } - public static class TextModifyOperation extends UndoOperation<TextView> { + /** + * An operation to undo a single "edit" to a text view. + */ + public static class TextModifyOperation extends UndoOperation<Editor> { int mRangeStart, mRangeEnd; CharSequence mOldText; @@ -4277,8 +4323,8 @@ public class Editor { private void swapText() { // Both undo and redo involves swapping the contents of the range // in the text view with our local text. - TextView tv = getOwnerData(); - Editable editable = (Editable)tv.getText(); + Editor editor = getOwnerData(); + Editable editable = (Editable)editor.mTextView.getText(); CharSequence curText; if (mRangeStart >= mRangeEnd) { curText = null; @@ -4309,14 +4355,17 @@ public class Editor { public static final Parcelable.ClassLoaderCreator<TextModifyOperation> CREATOR = new Parcelable.ClassLoaderCreator<TextModifyOperation>() { + @Override public TextModifyOperation createFromParcel(Parcel in) { return new TextModifyOperation(in, null); } + @Override public TextModifyOperation createFromParcel(Parcel in, ClassLoader loader) { return new TextModifyOperation(in, loader); } + @Override public TextModifyOperation[] newArray(int size) { return new TextModifyOperation[size]; } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index f33ef753fb74..92977310233e 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -47,6 +47,7 @@ import android.os.AsyncTask; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; +import android.os.ParcelableParcel; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; @@ -1612,7 +1613,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @hide */ public final UndoManager getUndoManager() { - return mEditor == null ? null : mEditor.mUndoManager; + // TODO: Consider supporting a global undo manager. + throw new UnsupportedOperationException("not implemented"); } /** @@ -1630,22 +1632,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @hide */ public final void setUndoManager(UndoManager undoManager, String tag) { - if (undoManager != null) { - createEditorIfNeeded(); - mEditor.mUndoManager = undoManager; - mEditor.mUndoOwner = undoManager.getOwner(tag, this); - mEditor.mUndoInputFilter = new Editor.UndoInputFilter(mEditor); - if (!(mText instanceof Editable)) { - setText(mText, BufferType.EDITABLE); - } - - setFilters((Editable) mText, mFilters); - } else if (mEditor != null) { - // XXX need to destroy all associated state. - mEditor.mUndoManager = null; - mEditor.mUndoOwner = null; - mEditor.mUndoInputFilter = null; - } + // TODO: Consider supporting a global undo manager. An implementation will need to: + // * createEditorIfNeeded() + // * Promote to BufferType.EDITABLE if needed. + // * Update the UndoManager and UndoOwner. + // Likewise it will need to be able to restore the default UndoManager. + throw new UnsupportedOperationException("not implemented"); } /** @@ -3899,6 +3891,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener ss.error = getError(); + if (mEditor != null) { + ss.editorState = mEditor.saveInstanceState(); + } return ss; } @@ -3968,6 +3963,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } }); } + + if (ss.editorState != null) { + createEditorIfNeeded(); + mEditor.restoreInstanceState(ss.editorState); + } } /** @@ -8375,14 +8375,19 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener @Override public boolean onKeyShortcut(int keyCode, KeyEvent event) { - final int filteredMetaState = event.getMetaState() & ~KeyEvent.META_CTRL_MASK; - if (KeyEvent.metaStateHasNoModifiers(filteredMetaState)) { + if (event.hasModifiers(KeyEvent.META_CTRL_ON)) { + // Handle Ctrl-only shortcuts. switch (keyCode) { case KeyEvent.KEYCODE_A: if (canSelectText()) { return onTextContextMenuItem(ID_SELECT_ALL); } break; + case KeyEvent.KEYCODE_Z: + if (canUndo()) { + return onTextContextMenuItem(ID_UNDO); + } + break; case KeyEvent.KEYCODE_X: if (canCut()) { return onTextContextMenuItem(ID_CUT); @@ -8399,6 +8404,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } break; } + } else if (event.hasModifiers(KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON)) { + // Handle Ctrl-Shift shortcuts. + switch (keyCode) { + case KeyEvent.KEYCODE_Z: + if (canRedo()) { + return onTextContextMenuItem(ID_REDO); + } + break; + } } return super.onKeyShortcut(keyCode, event); } @@ -8775,6 +8789,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } static final int ID_SELECT_ALL = android.R.id.selectAll; + static final int ID_UNDO = android.R.id.undo; + static final int ID_REDO = android.R.id.redo; static final int ID_CUT = android.R.id.cut; static final int ID_COPY = android.R.id.copy; static final int ID_PASTE = android.R.id.paste; @@ -8805,6 +8821,18 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener selectAllText(); return true; + case ID_UNDO: + if (mEditor != null) { + mEditor.undo(); + } + return true; // Returns true even if nothing was undone. + + case ID_REDO: + if (mEditor != null) { + mEditor.redo(); + } + return true; // Returns true even if nothing was undone. + case ID_PASTE: paste(min, max); return true; @@ -8934,7 +8962,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @hide */ protected void stopSelectionActionMode() { - mEditor.stopSelectionActionMode(); + if (mEditor != null) { + mEditor.stopSelectionActionMode(); + } + } + + boolean canUndo() { + return mEditor != null && mEditor.canUndo(); + } + + boolean canRedo() { + return mEditor != null && mEditor.canRedo(); } boolean canCut() { @@ -9304,6 +9342,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener CharSequence text; boolean frozenWithFocus; CharSequence error; + ParcelableParcel editorState; // Optional state from Editor. SavedState(Parcelable superState) { super(superState); @@ -9323,6 +9362,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener out.writeInt(1); TextUtils.writeToParcel(error, out, flags); } + + if (editorState == null) { + out.writeInt(0); + } else { + out.writeInt(1); + editorState.writeToParcel(out, flags); + } } @Override @@ -9358,6 +9404,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (in.readInt() != 0) { error = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in); } + + if (in.readInt() != 0) { + editorState = ParcelableParcel.CREATOR.createFromParcel(in); + } } } diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index c9b44bebc626..a55fe9ad78a7 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -399,7 +399,7 @@ class ZygoteConnection { throws IllegalArgumentException { int curArg = 0; - boolean seenRuntimeArgs = true; + boolean seenRuntimeArgs = false; for ( /* curArg */ ; curArg < args.length; curArg++) { String arg = args[curArg]; @@ -533,14 +533,18 @@ class ZygoteConnection { } } - if (!seenRuntimeArgs) { - throw new IllegalArgumentException("Unexpected argument : " + args[curArg]); - } - - remainingArgs = new String[args.length - curArg]; + if (abiListQuery) { + if (args.length - curArg > 0) { + throw new IllegalArgumentException("Unexpected arguments after --query-abi-list."); + } + } else { + if (!seenRuntimeArgs) { + throw new IllegalArgumentException("Unexpected argument : " + args[curArg]); + } - System.arraycopy(args, curArg, remainingArgs, 0, - remainingArgs.length); + remainingArgs = new String[args.length - curArg]; + System.arraycopy(args, curArg, remainingArgs, 0, remainingArgs.length); + } } } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 035b017207d2..400ea3782b3e 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -504,8 +504,8 @@ public class ZygoteInit { "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007", "--capabilities=" + capabilities + "," + capabilities, - "--runtime-init", "--nice-name=system_server", + "--runtime-args", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml index bd24f3e4212f..1f4d37c569fe 100644 --- a/core/res/res/values/ids.xml +++ b/core/res/res/values/ids.xml @@ -89,4 +89,6 @@ <item type="id" name="parentMatrix" /> <item type="id" name="statusBarBackground" /> <item type="id" name="navigationBarBackground" /> + <item type="id" name="undo" /> + <item type="id" name="redo" /> </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index cfff420ef619..8814138da07b 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2634,4 +2634,9 @@ <public type="style" name="Theme.Material.DayNight.Panel" /> <public type="style" name="Theme.Material.Light.LightStatusBar" /> + <!-- Context menu ID for the "Undo" menu item to undo the last text edit operation. --> + <public type="id" name="undo" /> + <!-- Context menu ID for the "Redo" menu item to redo the last text edit operation. --> + <public type="id" name="redo" /> + </resources> diff --git a/docs/html/design/style/iconography.jd b/docs/html/design/style/iconography.jd index 1a9275338e90..75f541a44735 100644 --- a/docs/html/design/style/iconography.jd +++ b/docs/html/design/style/iconography.jd @@ -536,7 +536,7 @@ see <a href="{@docRoot}guide/topics/resources/providing-resources.html">Providin </p> <p> For more information about using the mipmap folders, see -<a href="{@docRoot}tools/project/index.html#mipmap">Managing Projects Overview</a>.</p> +<a href="{@docRoot}tools/projects/index.html#mipmap">Managing Projects Overview</a>.</p> <h3 id="xxxhdpi-launcher">Provide an xxx-high-density launcher icon</h3> diff --git a/docs/html/guide/practices/screens_support.jd b/docs/html/guide/practices/screens_support.jd index 7c963dd84269..b6f1c49c7c78 100644 --- a/docs/html/guide/practices/screens_support.jd +++ b/docs/html/guide/practices/screens_support.jd @@ -368,7 +368,7 @@ folders. The Android system retains the resources in these density-specific fold mipmap-xxxhdpi, regardless of the screen resolution of the device where your app is installed. This behavior allows launcher apps to pick the best resolution icon for your app to display on the home screen. For more information about using the mipmap folders, see -<a href="{@docRoot}tools/project/index.html#mipmap">Managing Projects Overview</a>. +<a href="{@docRoot}tools/projects/index.html#mipmap">Managing Projects Overview</a>. </p> diff --git a/docs/html/guide/topics/resources/providing-resources.jd b/docs/html/guide/topics/resources/providing-resources.jd index 98e7c96aa3ab..fc7997071b50 100644 --- a/docs/html/guide/topics/resources/providing-resources.jd +++ b/docs/html/guide/topics/resources/providing-resources.jd @@ -76,7 +76,7 @@ icons, and a string resource file. The resource directory names are important and are described in table 1.</p> <p class="note"><strong>Note:</strong> For more information about using the mipmap folders, see -<a href="{@docRoot}tools/project/index.html#mipmap">Managing Projects Overview</a>.</p> +<a href="{@docRoot}tools/projects/index.html#mipmap">Managing Projects Overview</a>.</p> <p class="table-caption" id="table1"><strong>Table 1.</strong> Resource directories supported inside project {@code res/} directory.</p> diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd index af6f6b8fdd48..a43ba3c89f96 100644 --- a/docs/html/sdk/index.jd +++ b/docs/html/sdk/index.jd @@ -4,27 +4,27 @@ page.template=sdk header.hide=1 page.metaDescription=Download the official Android IDE and developer tools to build apps for Android phones, tablets, wearables, TVs, and more. -studio.version=1.0.1 +studio.version=1.1.0 -studio.linux_bundle_download=android-studio-ide-135.1641136-linux.zip -studio.linux_bundle_bytes=243917559 -studio.linux_bundle_checksum=7c8f2d0cec21b98984cdba45ab5a25f26d67f23a +studio.linux_bundle_download=android-studio-ide-135.1740770-linux.zip +studio.linux_bundle_bytes=259336386 +studio.linux_bundle_checksum=e8d166559c50a484f83ebfec6731cc0e3f259208 -studio.mac_bundle_download=android-studio-ide-1641136.dmg -studio.mac_bundle_bytes=245729073 -studio.mac_bundle_checksum=49506ba2cf6b56be4f7d07e6a00c4ec3ba2249d5 +studio.mac_bundle_download=android-studio-ide-135.1740770-mac.dmg +studio.mac_bundle_bytes=261303345 +studio.mac_bundle_checksum=f9745d0fec1eefd498f6160a2d6a1b5247d4cda3 -studio.win_bundle_exe_download=android-studio-bundle-135.1641136.exe -studio.win_bundle_exe_bytes=868344232 -studio.win_bundle_exe_checksum=9c1c8ea6aa17fb74e0593c62fd48ee62a8950be7 +studio.win_bundle_exe_download=android-studio-bundle-135.1740770-windows.exe +studio.win_bundle_exe_bytes=856233768 +studio.win_bundle_exe_checksum=7484b9989d2914e1de30995fbaa97a271a514b3f -studio.win_notools_exe_download=android-studio-ide-135.1641136.exe -studio.win_notools_exe_bytes=260272840 -studio.win_notools_exe_checksum=464d1c5497ab3d1bdef441365791ab36c89cd5ae +studio.win_notools_exe_download=android-studio-ide-135.1740770-windows.exe +studio.win_notools_exe_bytes=242135128 +studio.win_notools_exe_checksum=5ea77661cd2300cea09e8e34f4a2219a0813911f -studio.win_bundle_download=android-studio-ide-135.1641136-windows.zip -studio.win_bundle_bytes=246249059 -studio.win_bundle_checksum=6d6856aca83f6ff747ca40b10f70edfbbcccd91c +studio.win_bundle_download=android-studio-ide-135.1740770-windows.zip +studio.win_bundle_bytes=261667054 +studio.win_bundle_checksum=e903f17cc6a57c7e3d460c4555386e3e65c6b4eb diff --git a/docs/html/training/multiscreen/screendensities.jd b/docs/html/training/multiscreen/screendensities.jd index 1fc5904cfece..64e70fd6eb35 100644 --- a/docs/html/training/multiscreen/screendensities.jd +++ b/docs/html/training/multiscreen/screendensities.jd @@ -154,7 +154,7 @@ appropriate bitmap based on the screen's dpi.</p> <p class="note"><strong>Note:</strong> You should place all launcher icons in the <code>res/mipmap-[density]/</code> folders, rather than <code>drawable/</code> folders to ensure launcher apps use the best resolution icon. For more information about using the mipmap folders, see -<a href="{@docRoot}tools/project/index.html#mipmap">Managing Projects Overview</a>.</p> +<a href="{@docRoot}tools/projects/index.html#mipmap">Managing Projects Overview</a>.</p> <p>For more tips and guidelines for creating icon assets for your application, see the <a href="{@docRoot}guide/practices/ui_guidelines/icon_design.html">Icon Design diff --git a/docs/html/training/volley/request.jd b/docs/html/training/volley/request.jd index d8ccab2f07dc..8a7dc6255e5c 100644 --- a/docs/html/training/volley/request.jd +++ b/docs/html/training/volley/request.jd @@ -85,7 +85,7 @@ mImageView = (ImageView) findViewById(R.id.myImage); // Retrieves an image specified by the URL, displays it in the UI. ImageRequest request = new ImageRequest(url, - new Response.Listener<Bitmap>() { + new Response.Listener<Bitmap>() { @Override public void onResponse(Bitmap bitmap) { mImageView.setImageBitmap(bitmap); @@ -257,7 +257,7 @@ mTxtDisplay = (TextView) findViewById(R.id.txtDisplay); String url = "http://my-json-feed"; JsonObjectRequest jsObjRequest = new JsonObjectRequest - (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { + (Request.Method.GET, url, null, new Response.Listener<JSONObject>() { @Override public void onResponse(JSONObject response) { diff --git a/docs/html/training/volley/simple.jd b/docs/html/training/volley/simple.jd index 942c57f0af75..ecb5fde62235 100644 --- a/docs/html/training/volley/simple.jd +++ b/docs/html/training/volley/simple.jd @@ -63,7 +63,7 @@ String url ="http://www.google.com"; // Request a string response from the provided URL. StringRequest stringRequest = new StringRequest(Request.Method.GET, url, - new Response.Listener<String>() { + new Response.Listener<String>() { @Override public void onResponse(String response) { // Display the first 500 characters of the response string. diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java index ca242e4bcbe0..97919a9fa32f 100644 --- a/media/java/android/media/AudioAttributes.java +++ b/media/java/android/media/AudioAttributes.java @@ -209,8 +209,23 @@ public final class AudioAttributes implements Parcelable { @SystemApi public final static int FLAG_HW_HOTWORD = 0x1 << 5; + /** + * @hide + * Flag requesting audible playback even under limited interruptions. + */ + @SystemApi + public final static int FLAG_BYPASS_INTERRUPTION_POLICY = 0x1 << 6; + + /** + * @hide + * Flag requesting audible playback even when the underlying stream is muted. + */ + @SystemApi + public final static int FLAG_BYPASS_MUTE = 0x1 << 7; + private final static int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO | - FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD; + FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY | + FLAG_BYPASS_MUTE; private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED | FLAG_HW_AV_SYNC; private int mUsage = USAGE_UNKNOWN; diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index caccb6efd382..cd7823413401 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -1178,6 +1178,9 @@ public class AudioTrack } private boolean isRestricted() { + if ((mAttributes.getFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) { + return false; + } try { final int usage = AudioAttributes.usageForLegacyStreamType(mStreamType); final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, usage, diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java index 615dac204f7b..fc372ebd62d0 100644 --- a/media/java/android/media/MediaPlayer.java +++ b/media/java/android/media/MediaPlayer.java @@ -604,6 +604,7 @@ public class MediaPlayer implements SubtitleController.Listener private final IAppOpsService mAppOps; private int mStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE; private int mUsage = -1; + private boolean mBypassInterruptionPolicy; /** * Default constructor. Consider using one of the create() methods for @@ -1169,6 +1170,9 @@ public class MediaPlayer implements SubtitleController.Listener private native void _start() throws IllegalStateException; private boolean isRestricted() { + if (mBypassInterruptionPolicy) { + return false; + } try { final int usage = mUsage != -1 ? mUsage : AudioAttributes.usageForLegacyStreamType(getAudioStreamType()); @@ -1560,6 +1564,8 @@ public class MediaPlayer implements SubtitleController.Listener throw new IllegalArgumentException(msg); } mUsage = attributes.getUsage(); + mBypassInterruptionPolicy = (attributes.getFlags() + & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0; Parcel pattributes = Parcel.obtain(); attributes.writeToParcel(pattributes, AudioAttributes.FLATTEN_TAGS); setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, pattributes); diff --git a/media/java/android/media/SoundPool.java b/media/java/android/media/SoundPool.java index 32d5b8297531..db6b38b3967e 100644 --- a/media/java/android/media/SoundPool.java +++ b/media/java/android/media/SoundPool.java @@ -608,6 +608,9 @@ public class SoundPool { int priority, int loop, float rate); private boolean isRestricted() { + if ((mAttributes.getFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0) { + return false; + } try { final int mode = mAppOps.checkAudioOperation(AppOpsManager.OP_PLAY_AUDIO, mAttributes.getUsage(), diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index 1d8cb466a51d..f7bbce060289 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -79,7 +79,8 @@ android:layout_width="@dimen/notification_panel_width" android:layout_height="match_parent" android:layout_gravity="@integer/notification_panel_layout_gravity" - android:layout_marginBottom="@dimen/close_handle_underlap" /> + android:layout_marginBottom="@dimen/close_handle_underlap" + android:importantForAccessibility="no" /> <ViewStub android:id="@+id/keyguard_user_switcher" diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index b1ac733f8f2a..e0b4c2f1efb0 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -193,8 +193,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView } // Start loading tasks according to the load plan - ArrayList<TaskStack> stacks = plan.getAllTaskStacks(); - if (stacks.size() == 0) { + if (!plan.hasTasks()) { loader.preloadTasks(plan, mConfig.launchedFromHome); } RecentsTaskLoadPlan.Options loadOpts = new RecentsTaskLoadPlan.Options(); @@ -203,11 +202,11 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView loadOpts.numVisibleTaskThumbnails = mConfig.launchedNumVisibleThumbnails; loader.loadTasks(this, plan, loadOpts); - boolean hasTasks = plan.hasTasks(); - if (hasTasks) { + ArrayList<TaskStack> stacks = plan.getAllTaskStacks(); + mConfig.launchedWithNoRecentTasks = !plan.hasTasks(); + if (!mConfig.launchedWithNoRecentTasks) { mRecentsView.setTaskStacks(stacks); } - mConfig.launchedWithNoRecentTasks = !hasTasks; // Create the home intent runnable Intent homeIntent = new Intent(Intent.ACTION_MAIN, null); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 231831992b62..21975b01f8fd 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -879,7 +879,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // Start the focus animation when alt-tabbing if (mConfig.launchedWithAltTab && !mConfig.launchedHasConfigurationChanged) { - TaskView tv = taskViews.get(mFocusedTaskIndex); + TaskView tv = getChildViewForTask(mStack.getTasks().get(mFocusedTaskIndex)); if (tv != null) { tv.setFocusedTask(true); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java index b827acca2369..81e960a63678 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java @@ -32,12 +32,10 @@ import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.PorterDuffColorFilter; import android.graphics.PorterDuffXfermode; -import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.RippleDrawable; import android.util.AttributeSet; -import android.view.MotionEvent; import android.view.View; import android.view.ViewOutlineProvider; import android.widget.FrameLayout; @@ -104,11 +102,10 @@ public class TaskViewHeader extends FrameLayout { }); // Load the dismiss resources - Resources res = context.getResources(); - mLightDismissDrawable = res.getDrawable(R.drawable.recents_dismiss_light); - mDarkDismissDrawable = res.getDrawable(R.drawable.recents_dismiss_dark); + mLightDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_light); + mDarkDismissDrawable = context.getDrawable(R.drawable.recents_dismiss_dark); mDismissContentDescription = - res.getString(R.string.accessibility_recents_item_will_be_dismissed); + context.getString(R.string.accessibility_recents_item_will_be_dismissed); // Configure the highlight paint if (sHighlightPaint == null) { @@ -283,23 +280,26 @@ public class TaskViewHeader extends FrameLayout { } if (focused) { + int currentColor = mBackgroundColor; int secondaryColor = getSecondaryColor(mCurrentPrimaryColor, mCurrentPrimaryColorIsDark); int[][] states = new int[][] { + new int[] {}, new int[] { android.R.attr.state_enabled }, new int[] { android.R.attr.state_pressed } }; int[] newStates = new int[]{ + 0, android.R.attr.state_enabled, android.R.attr.state_pressed }; int[] colors = new int[] { + currentColor, secondaryColor, secondaryColor }; mBackground.setColor(new ColorStateList(states, colors)); mBackground.setState(newStates); // Pulse the background color - int currentColor = mBackgroundColor; int lightPrimaryColor = getSecondaryColor(mCurrentPrimaryColor, mCurrentPrimaryColorIsDark); ValueAnimator backgroundColor = ValueAnimator.ofObject(new ArgbEvaluator(), currentColor, lightPrimaryColor); @@ -326,7 +326,7 @@ public class TaskViewHeader extends FrameLayout { mFocusAnimator = new AnimatorSet(); mFocusAnimator.playTogether(backgroundColor, translation); - mFocusAnimator.setStartDelay(750); + mFocusAnimator.setStartDelay(150); mFocusAnimator.setDuration(750); mFocusAnimator.start(); } else { diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java index 4ea62ecd0ae6..02c8cce643b1 100644 --- a/services/core/java/com/android/server/audio/AudioService.java +++ b/services/core/java/com/android/server/audio/AudioService.java @@ -581,8 +581,7 @@ public class AudioService extends IAudioService.Stub { AudioSystem.setErrorCallback(mAudioSystemCallback); - boolean cameraSoundForced = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_camera_sound_forced); + boolean cameraSoundForced = readCameraSoundForced(); mCameraSoundForced = new Boolean(cameraSoundForced); sendMsg(mAudioHandler, MSG_SET_FORCE_USE, @@ -1107,11 +1106,6 @@ public class AudioService extends IAudioService.Stub { for (int stream = 0; stream < mStreamStates.length; stream++) { if (streamTypeAlias == mStreamVolumeAlias[stream]) { mStreamStates[stream].mute(state); - - Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION); - intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, stream); - intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state); - sendBroadcastToAll(intent); } } } else if ((direction == AudioManager.ADJUST_RAISE) && @@ -1459,16 +1453,6 @@ public class AudioService extends IAudioService.Stub { flags = updateFlagsForSystemAudio(flags); } mVolumeController.postVolumeChanged(streamType, flags); - - if ((flags & AudioManager.FLAG_FIXED_VOLUME) == 0) { - oldIndex = (oldIndex + 5) / 10; - index = (index + 5) / 10; - Intent intent = new Intent(AudioManager.VOLUME_CHANGED_ACTION); - intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, streamType); - intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index); - intent.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex); - sendBroadcastToAll(intent); - } } // If Hdmi-CEC system audio mode is on, we show volume bar only when TV @@ -3506,6 +3490,7 @@ public class AudioService extends IAudioService.Stub { private int mIndexMax; private final ConcurrentHashMap<Integer, Integer> mIndex = new ConcurrentHashMap<Integer, Integer>(8, 0.75f, 4); + private final Intent mVolumeChanged; private VolumeStreamState(String settingName, int streamType) { @@ -3517,6 +3502,8 @@ public class AudioService extends IAudioService.Stub { mIndexMax *= 10; readSettings(); + mVolumeChanged = new Intent(AudioManager.VOLUME_CHANGED_ACTION); + mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); } public String getSettingNameForDevice(int device) { @@ -3631,8 +3618,10 @@ public class AudioService extends IAudioService.Stub { } public boolean setIndex(int index, int device) { + boolean changed = false; + int oldIndex; synchronized (VolumeStreamState.class) { - int oldIndex = getIndex(device); + oldIndex = getIndex(device); index = getValidIndex(index); synchronized (mCameraSoundForced) { if ((mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED) && mCameraSoundForced) { @@ -3641,7 +3630,8 @@ public class AudioService extends IAudioService.Stub { } mIndex.put(device, index); - if (oldIndex != index) { + changed = oldIndex != index; + if (changed) { // Apply change to all streams using this one as alias // if changing volume of current device, also change volume of current // device on aliased stream @@ -3659,11 +3649,16 @@ public class AudioService extends IAudioService.Stub { } } } - return true; - } else { - return false; } } + if (changed) { + oldIndex = (oldIndex + 5) / 10; + index = (index + 5) / 10; + mVolumeChanged.putExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, index); + mVolumeChanged.putExtra(AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, oldIndex); + sendBroadcastToAll(mVolumeChanged); + } + return changed; } public int getIndex(int device) { @@ -3720,9 +3715,12 @@ public class AudioService extends IAudioService.Stub { } public void mute(boolean state) { + boolean changed = false; synchronized (VolumeStreamState.class) { if (state != mIsMuted) { + changed = true; mIsMuted = state; + // Set the new mute volume. This propagates the values to // the audio system, otherwise the volume won't be changed // at the lower level. @@ -3734,6 +3732,13 @@ public class AudioService extends IAudioService.Stub { this, 0); } } + if (changed) { + // Stream mute changed, fire the intent. + Intent intent = new Intent(AudioManager.STREAM_MUTE_CHANGED_ACTION); + intent.putExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE, mStreamType); + intent.putExtra(AudioManager.EXTRA_STREAM_VOLUME_MUTED, state); + sendBroadcastToAll(intent); + } } public int getStreamType() { @@ -5071,6 +5076,12 @@ public class AudioService extends IAudioService.Stub { return mMediaFocusControl.getCurrentAudioFocus(); } + private boolean readCameraSoundForced() { + return SystemProperties.getBoolean("audio.camerasound.force", false) || + mContext.getResources().getBoolean( + com.android.internal.R.bool.config_camera_sound_forced); + } + //========================================================================================== // Device orientation //========================================================================================== @@ -5101,8 +5112,7 @@ public class AudioService extends IAudioService.Stub { null, 0); - boolean cameraSoundForced = mContext.getResources().getBoolean( - com.android.internal.R.bool.config_camera_sound_forced); + boolean cameraSoundForced = readCameraSoundForced(); synchronized (mSettingsLock) { boolean cameraSoundForcedChanged = false; synchronized (mCameraSoundForced) { @@ -5517,6 +5527,7 @@ public class AudioService extends IAudioService.Stub { pw.print(" mPendingVolumeCommand="); pw.println(mPendingVolumeCommand); pw.print(" mMusicActiveMs="); pw.println(mMusicActiveMs); pw.print(" mMcc="); pw.println(mMcc); + pw.print(" mCameraSoundForced="); pw.println(mCameraSoundForced); pw.print(" mHasVibrator="); pw.println(mHasVibrator); pw.print(" mControllerService="); pw.println(mControllerService); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 7ff7827764b3..8170835c1cff 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -100,6 +100,7 @@ import com.android.internal.R; import com.android.internal.os.storage.ExternalStorageFormatter; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.JournaledFile; +import com.android.internal.util.Preconditions; import com.android.internal.util.XmlUtils; import com.android.internal.widget.LockPatternUtils; import com.android.server.LocalServices; @@ -1920,13 +1921,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); validateQualityConstant(quality); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); if (ap.passwordQuality != quality) { @@ -1969,11 +1968,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); if (ap.minimumPasswordLength != length) { @@ -2016,11 +2013,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); if (ap.passwordHistoryLength != length) { @@ -2063,14 +2058,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); + Preconditions.checkArgumentNonnegative(timeout, "Timeout must be >= 0 ms"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } - if (timeout < 0) { - throw new IllegalArgumentException("Timeout must be >= 0 ms"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_EXPIRE_PASSWORD); // Calling this API automatically bumps the expiration date @@ -2232,11 +2223,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); if (ap.minimumPasswordUpperCase != length) { @@ -2276,11 +2265,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } public void setPasswordMinimumLowerCase(ComponentName who, int length) { + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); if (ap.minimumPasswordLowerCase != length) { @@ -2323,11 +2310,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); if (ap.minimumPasswordLetters != length) { @@ -2370,11 +2355,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); if (ap.minimumPasswordNumeric != length) { @@ -2417,11 +2400,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); if (ap.minimumPasswordSymbols != length) { @@ -2464,11 +2445,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_LIMIT_PASSWORD); if (ap.minimumPasswordNonLetter != length) { @@ -2561,11 +2540,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } // This API can only be called by an active device admin, // so try to retrieve it to check that the caller is one. getActiveAdminForCallerLocked(who, @@ -2772,11 +2749,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_FORCE_LOCK); if (ap.maximumTimeToUnlock != timeMs) { @@ -2955,9 +2930,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean installKeyPair(ComponentName who, byte[] privKey, byte[] cert, String alias) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); } @@ -3297,9 +3270,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return null; } synchronized(this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } + Preconditions.checkNotNull(who, "ComponentName is null"); // Only check if owner has set global proxy. We don't allow other users to set it. DevicePolicyData policy = getUserData(UserHandle.USER_OWNER); @@ -3435,12 +3406,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { // Check for permissions - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } // Only owner can set storage encryption if (userHandle != UserHandle.USER_OWNER || UserHandle.getCallingUserId() != UserHandle.USER_OWNER) { @@ -3571,11 +3540,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (ap.disableScreenCapture != disabled) { @@ -3630,11 +3597,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin admin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); if (admin.requireAutoTime != required) { @@ -3682,11 +3647,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DISABLE_CAMERA); if (ap.disableCamera != disabled) { @@ -3731,12 +3694,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); enforceNotManagedProfile(userHandle, "disable keyguard features"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES); if (ap.disabledKeyguardFeatures != which) { @@ -3880,9 +3841,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void clearDeviceOwner(String packageName) { - if (packageName == null) { - throw new NullPointerException("packageName is null"); - } + Preconditions.checkNotNull(packageName, "packageName is null"); try { int uid = mContext.getPackageManager().getPackageUid(packageName, 0); if (uid != Binder.getCallingUid()) { @@ -4007,12 +3966,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); synchronized (this) { - // Check for permissions - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } // Check if this is the profile owner who is calling getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); int userId = UserHandle.getCallingUserId(); @@ -4034,12 +3990,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setProfileName(ComponentName who, String profileName) { + Preconditions.checkNotNull(who, "ComponentName is null"); int userId = UserHandle.getCallingUserId(); - - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } - // Check if this is the profile owner (includes device owner). getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); @@ -4215,12 +4167,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void addPersistentPreferredActivity(ComponentName who, IntentFilter filter, ComponentName activity) { + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); - synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); IPackageManager pm = AppGlobals.getPackageManager(); @@ -4237,12 +4186,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void clearPackagePersistentPreferredActivities(ComponentName who, String packageName) { + Preconditions.checkNotNull(who, "ComponentName is null"); final int userHandle = UserHandle.getCallingUserId(); - synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); IPackageManager pm = AppGlobals.getPackageManager(); @@ -4259,12 +4205,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setApplicationRestrictions(ComponentName who, String packageName, Bundle settings) { + Preconditions.checkNotNull(who, "ComponentName is null"); final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId()); - synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); long id = Binder.clearCallingIdentity(); @@ -4281,15 +4224,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(admin, "admin is null"); + Preconditions.checkNotNull(agent, "agent is null"); final int userHandle = UserHandle.getCallingUserId(); enforceNotManagedProfile(userHandle, "set trust agent configuration"); synchronized (this) { - if (admin == null) { - throw new NullPointerException("admin is null"); - } - if (agent == null) { - throw new NullPointerException("agent is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(admin, DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES); ap.trustAgentInfos.put(agent.flattenToString(), new TrustAgentInfo(args)); @@ -4303,10 +4242,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return null; } + Preconditions.checkNotNull(agent, "agent null"); enforceCrossUserPermission(userHandle); - if (agent == null) { - throw new NullPointerException("agent is null"); - } synchronized (this) { final String componentName = agent.flattenToString(); @@ -4359,10 +4296,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setRestrictionsProvider(ComponentName who, ComponentName permissionProvider) { + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); int userHandle = UserHandle.getCallingUserId(); @@ -4384,11 +4319,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } public void addCrossProfileIntentFilter(ComponentName who, IntentFilter filter, int flags) { + Preconditions.checkNotNull(who, "ComponentName is null"); int callingUserId = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); IPackageManager pm = AppGlobals.getPackageManager(); @@ -4411,11 +4344,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } public void clearCrossProfileIntentFilters(ComponentName who) { + Preconditions.checkNotNull(who, "ComponentName is null"); int callingUserId = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); IPackageManager pm = AppGlobals.getPackageManager(); long id = Binder.clearCallingIdentity(); @@ -4485,9 +4416,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return false; } - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } + Preconditions.checkNotNull(who, "ComponentName is null"); if (packageList != null) { int userId = UserHandle.getCallingUserId(); @@ -4532,10 +4461,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return null; } - - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { ActiveAdmin admin = getActiveAdminForCallerLocked(who, @@ -4640,9 +4566,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return false; } - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } + Preconditions.checkNotNull(who, "ComponentName is null"); // TODO When InputMethodManager supports per user calls remove // this restriction. @@ -4685,10 +4609,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return null; } - - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { ActiveAdmin admin = getActiveAdminForCallerLocked(who, @@ -4761,10 +4682,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public UserHandle createUser(ComponentName who, String name) { + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); long id = Binder.clearCallingIdentity(); @@ -4815,10 +4734,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean removeUser(ComponentName who, UserHandle userHandle) { + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); long id = Binder.clearCallingIdentity(); @@ -4832,10 +4749,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean switchUser(ComponentName who, UserHandle userHandle) { + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); long id = Binder.clearCallingIdentity(); @@ -4856,12 +4771,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public Bundle getApplicationRestrictions(ComponentName who, String packageName) { + Preconditions.checkNotNull(who, "ComponentName is null"); final UserHandle userHandle = new UserHandle(UserHandle.getCallingUserId()); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); long id = Binder.clearCallingIdentity(); @@ -4875,12 +4788,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setUserRestriction(ComponentName who, String key, boolean enabled) { + Preconditions.checkNotNull(who, "ComponentName is null"); final UserHandle user = new UserHandle(UserHandle.getCallingUserId()); final int userHandle = user.getIdentifier(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); boolean isDeviceOwner = isDeviceOwner(activeAdmin.info.getPackageName()); @@ -4982,11 +4893,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean setApplicationHidden(ComponentName who, String packageName, boolean hidden) { + Preconditions.checkNotNull(who, "ComponentName is null"); int callingUserId = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); long id = Binder.clearCallingIdentity(); @@ -5005,11 +4914,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean isApplicationHidden(ComponentName who, String packageName) { + Preconditions.checkNotNull(who, "ComponentName is null"); int callingUserId = UserHandle.getCallingUserId(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); long id = Binder.clearCallingIdentity(); @@ -5028,11 +4935,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void enableSystemApp(ComponentName who, String packageName) { + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } - // This API can only be called by an active device admin, // so try to retrieve it to check that the caller is one. getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); @@ -5073,11 +4977,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public int enableSystemAppWithIntent(ComponentName who, Intent intent) { + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } - // This API can only be called by an active device admin, // so try to retrieve it to check that the caller is one. getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); @@ -5144,10 +5045,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin ap = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (disabled) { @@ -5185,12 +5084,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setUninstallBlocked(ComponentName who, String packageName, boolean uninstallBlocked) { + Preconditions.checkNotNull(who, "ComponentName is null"); final int userId = UserHandle.getCallingUserId(); - synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); long id = Binder.clearCallingIdentity(); @@ -5237,10 +5133,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return; } + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin admin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); if (admin.disableCallerId != disabled) { @@ -5255,12 +5149,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (!mHasFeature) { return false; } - + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } - ActiveAdmin admin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); return admin.disableCallerId; @@ -5281,13 +5171,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * Sets which packages may enter lock task mode. * * This function can only be called by the device owner. - * @param components The list of components allowed to enter lock task mode. + * @param packages The list of packages allowed to enter lock task mode. */ public void setLockTaskPackages(ComponentName who, String[] packages) throws SecurityException { + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); int userHandle = Binder.getCallingUserHandle().getIdentifier(); @@ -5309,15 +5197,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * This function returns the list of components allowed to start the task lock mode. */ public String[] getLockTaskPackages(ComponentName who) { + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); int userHandle = Binder.getCallingUserHandle().getIdentifier(); DevicePolicyData policy = getUserData(userHandle); - return policy.mLockTaskPackages.toArray(new String[0]); + return policy.mLockTaskPackages.toArray(new String[policy.mLockTaskPackages.size()]); } } @@ -5373,11 +5259,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setGlobalSetting(ComponentName who, String setting, String value) { final ContentResolver contentResolver = mContext.getContentResolver(); + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_DEVICE_OWNER); if (!GLOBAL_SETTINGS_WHITELIST.contains(setting)) { @@ -5396,13 +5280,11 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setSecureSetting(ComponentName who, String setting, String value) { + Preconditions.checkNotNull(who, "ComponentName is null"); int callingUserId = UserHandle.getCallingUserId(); final ContentResolver contentResolver = mContext.getContentResolver(); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } ActiveAdmin activeAdmin = getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); @@ -5427,10 +5309,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setMasterVolumeMuted(ComponentName who, boolean on) { + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); IAudioService iAudioService = IAudioService.Stub.asInterface( @@ -5447,12 +5327,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean isMasterVolumeMuted(ComponentName who) { - final ContentResolver contentResolver = mContext.getContentResolver(); - + Preconditions.checkNotNull(who, "ComponentName is null"); synchronized (this) { - if (who == null) { - throw new NullPointerException("ComponentName is null"); - } getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); AudioManager audioManager = diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 6c5f1c62a539..bcc1ccc439cf 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -83,6 +83,12 @@ public class TelecomManager { "android.telecom.action.SHOW_CALL_SETTINGS"; /** + * The {@link android.content.Intent} action used to show the respond via SMS settings page. + */ + public static final String ACTION_SHOW_RESPOND_VIA_SMS_SETTINGS = + "android.telecom.action.SHOW_RESPOND_VIA_SMS_SETTINGS"; + + /** * The {@link android.content.Intent} action used to show the settings page used to configure * {@link PhoneAccount} preferences. * @hide |