auto import from //branches/cupcake/...@127101

This commit is contained in:
The Android Open Source Project
2009-01-20 14:03:58 -08:00
parent 9266c558bf
commit 22f7dfd234
130 changed files with 2728 additions and 410 deletions

View File

@@ -1128,6 +1128,15 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
super(context, attrs, defStyle);
}
/**
* We never allow ACTV to automatically replace the text, since we use "jamSuggestionQuery"
* to do that. There's no point in letting ACTV do this here, because in the search UI,
* as soon as we click a suggestion, we're going to start shutting things down.
*/
@Override
public void replaceText(CharSequence text) {
}
/**
* We always return true, so that the effective threshold is "zero". This allows us
* to provide "null" suggestions such as "just show me some recent entries".

View File

@@ -72,6 +72,12 @@ public class BluetoothA2dp {
/** Playing implies connected */
public static final int STATE_PLAYING = 4;
/** Default priority for a2dp devices that should allow incoming
* connections */
public static final int PRIORITY_AUTO = 100;
/** Default priority for a2dp devices that should not allow incoming
* connections */
public static final int PRIORITY_OFF = 0;
private final IBluetoothA2dp mService;
private final Context mContext;
@@ -158,6 +164,66 @@ public class BluetoothA2dp {
}
}
/**
* Set priority of a2dp sink.
* Priority is a non-negative integer. By default paired sinks will have
* a priority of PRIORITY_AUTO, and unpaired headset PRIORITY_NONE (0).
* Sinks with priority greater than zero will accept incoming connections
* (if no sink is currently connected).
* Priority for unpaired sink must be PRIORITY_NONE.
* @param address Paired sink
* @param priority Integer priority, for example PRIORITY_AUTO or
* PRIORITY_NONE
* @return Result code, negative indicates an error
*/
public int setSinkPriority(String address, int priority) {
try {
return mService.setSinkPriority(address, priority);
} catch (RemoteException e) {
Log.w(TAG, "", e);
return BluetoothError.ERROR_IPC;
}
}
/**
* Get priority of a2dp sink.
* @param address Sink
* @return non-negative priority, or negative error code on error.
*/
public int getSinkPriority(String address) {
try {
return mService.getSinkPriority(address);
} catch (RemoteException e) {
Log.w(TAG, "", e);
return BluetoothError.ERROR_IPC;
}
}
/**
* Check class bits for possible A2DP Sink support.
* This is a simple heuristic that tries to guess if a device with the
* given class bits might be a A2DP Sink. It is not accurate for all
* devices. It tries to err on the side of false positives.
* @return True if this device might be a A2DP sink
*/
public static boolean doesClassMatchSink(int btClass) {
if (BluetoothClass.Service.hasService(btClass, BluetoothClass.Service.RENDER)) {
return true;
}
// By the A2DP spec, sinks must indicate the RENDER service.
// However we found some that do not (Chordette). So lets also
// match on some other class bits.
switch (BluetoothClass.Device.getDevice(btClass)) {
case BluetoothClass.Device.AUDIO_VIDEO_HIFI_AUDIO:
case BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES:
case BluetoothClass.Device.AUDIO_VIDEO_LOUDSPEAKER:
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
return true;
default:
return false;
}
}
/** Helper for converting a state to a string.
* For debug use only - strings are not internationalized.
* @hide

View File

@@ -57,7 +57,6 @@ public class BluetoothHeadset {
private IBluetoothHeadset mService;
private final Context mContext;
private final ServiceListener mServiceListener;
private ConnectHeadsetCallback mConnectHeadsetCallback;
/** There was an error trying to obtain the state */
public static final int STATE_ERROR = -1;
@@ -73,6 +72,11 @@ public class BluetoothHeadset {
/** Connection cancelled before completetion. */
public static final int RESULT_CANCELLED = 2;
/** Default priority for headsets that should be auto-connected */
public static final int PRIORITY_AUTO = 100;
/** Default priority for headsets that should not be auto-connected */
public static final int PRIORITY_OFF = 0;
/**
* An interface for notifying BluetoothHeadset IPC clients when they have
* been connected to the BluetoothHeadset service.
@@ -96,14 +100,6 @@ public class BluetoothHeadset {
public void onServiceDisconnected();
}
/**
* Interface for connectHeadset() callback.
* This callback can occur in the Binder thread.
*/
public interface ConnectHeadsetCallback {
public void onConnectHeadsetResult(String address, int resultCode);
}
/**
* Create a BluetoothHeadset proxy object.
*/
@@ -175,24 +171,18 @@ public class BluetoothHeadset {
* Request to initiate a connection to a headset.
* This call does not block. Fails if a headset is already connecting
* or connected.
* Will connect to the last connected headset if address is null.
* onConnectHeadsetResult() of your ConnectHeadsetCallback will be called
* on completition.
* @param address The Bluetooth Address to connect to, or null to connect
* to the last connected headset.
* @param callback Callback on result. Not called if false is returned. Can
* be null.
* to the last connected headset.
* Initiates auto-connection if address is null. Tries to connect to all
* devices with priority greater than PRIORITY_AUTO in descending order.
* @param address The Bluetooth Address to connect to, or null to
* auto-connect to the last connected headset.
* @return False if there was a problem initiating the connection
* procedure, and your callback will not be used. True if
* the connection procedure was initiated, in which case
* your callback is guarenteed to be called.
* procedure, and no further HEADSET_STATE_CHANGED intents
* will be expected.
*/
public boolean connectHeadset(String address, ConnectHeadsetCallback callback) {
public boolean connectHeadset(String address) {
if (mService != null) {
try {
if (mService.connectHeadset(address, mHeadsetCallback)) {
mConnectHeadsetCallback = callback;
if (mService.connectHeadset(address)) {
return true;
}
} catch (RemoteException e) {Log.e(TAG, e.toString());}
@@ -273,6 +263,71 @@ public class BluetoothHeadset {
return false;
}
/**
* Set priority of headset.
* Priority is a non-negative integer. By default paired headsets will have
* a priority of PRIORITY_AUTO, and unpaired headset PRIORITY_NONE (0).
* Headsets with priority greater than zero will be auto-connected, and
* incoming connections will be accepted (if no other headset is
* connected).
* Auto-connection occurs at the following events: boot, incoming phone
* call, outgoing phone call.
* Headsets with priority equal to zero, or that are unpaired, are not
* auto-connected.
* Incoming connections are ignored regardless of priority if there is
* already a headset connected.
* @param address Paired headset
* @param priority Integer priority, for example PRIORITY_AUTO or
* PRIORITY_NONE
* @return True if successful, false if there was some error.
*/
public boolean setPriority(String address, int priority) {
if (mService != null) {
try {
return mService.setPriority(address, priority);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
}
return false;
}
/**
* Get priority of headset.
* @param address Headset
* @return non-negative priority, or negative error code on error.
*/
public int getPriority(String address) {
if (mService != null) {
try {
return mService.getPriority(address);
} catch (RemoteException e) {Log.e(TAG, e.toString());}
} else {
Log.w(TAG, "Proxy not attached to service");
if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
}
return -1;
}
/**
* Check class bits for possible HSP or HFP support.
* This is a simple heuristic that tries to guess if a device with the
* given class bits might support HSP or HFP. It is not accurate for all
* devices. It tries to err on the side of false positives.
* @return True if this device might support HSP or HFP.
*/
public static boolean doesClassMatch(int btClass) {
switch (BluetoothClass.Device.getDevice(btClass)) {
case BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE:
case BluetoothClass.Device.AUDIO_VIDEO_WEARABLE_HEADSET:
case BluetoothClass.Device.AUDIO_VIDEO_CAR_AUDIO:
return true;
default:
return false;
}
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
if (DBG) Log.d(TAG, "Proxy object connected");
@@ -289,12 +344,4 @@ public class BluetoothHeadset {
}
}
};
private IBluetoothHeadsetCallback mHeadsetCallback = new IBluetoothHeadsetCallback.Stub() {
public void onConnectHeadsetResult(String address, int resultCode) {
if (mConnectHeadsetCallback != null) {
mConnectHeadsetCallback.onConnectHeadsetResult(address, resultCode);
}
}
};
}

View File

@@ -26,4 +26,6 @@ interface IBluetoothA2dp {
int disconnectSink(in String address);
List<String> listConnectedSinks();
int getSinkState(in String address);
int setSinkPriority(in String address, int priority);
int getSinkPriority(in String address);
}

View File

@@ -16,8 +16,6 @@
package android.bluetooth;
import android.bluetooth.IBluetoothHeadsetCallback;
/**
* System private API for Bluetooth Headset service
*
@@ -25,22 +23,12 @@ import android.bluetooth.IBluetoothHeadsetCallback;
*/
interface IBluetoothHeadset {
int getState();
String getHeadsetAddress();
// Request that the given headset be connected
// Assumes the given headset is already bonded
// Will disconnect any currently connected headset
// returns false if cannot start a connection (for example, there is
// already a pending connect). callback will always be called iff this
// returns true
boolean connectHeadset(in String address, in IBluetoothHeadsetCallback callback);
boolean connectHeadset(in String address);
void disconnectHeadset();
boolean isConnected(in String address);
boolean startVoiceRecognition();
boolean stopVoiceRecognition();
boolean setPriority(in String address, int priority);
int getPriority(in String address);
}

View File

@@ -1248,6 +1248,15 @@ public abstract class Context {
*/
public static final String INPUT_METHOD_SERVICE = "input_method";
/**
* Use with {@link #getSystemService} to retrieve a
* {@blink android.gadget.GadgetManager} for accessing wallpapers.
*
* @hide
* @see #getSystemService
*/
public static final String GADGET_SERVICE = "gadget";
/**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2006 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 android.gadget;
import android.content.Context;
import android.widget.RemoteViews;
/**
* GadgetHost provides the interaction with the Gadget Service for apps,
* like the home screen, that want to embed gadgets in their UI.
*/
public class GadgetHost {
public GadgetHost(Context context, int hostId) {
}
/**
* Start receiving onGadgetChanged calls for your gadgets. Call this when your activity
* becomes visible, i.e. from onStart() in your Activity.
*/
public void startListening() {
}
/**
* Stop receiving onGadgetChanged calls for your gadgets. Call this when your activity is
* no longer visible, i.e. from onStop() in your Activity.
*/
public void stopListening() {
}
/**
* Stop listening to changes for this gadget.
*/
public void gadgetRemoved(int gadgetId) {
}
/**
* Remove all records about gadget instances from the gadget manager. Call this when
* initializing your database, as it might be because of a data wipe.
*/
public void clearGadgets() {
}
public final GadgetHostView createView(Context context, int gadgetId, GadgetInfo gadget) {
GadgetHostView view = onCreateView(context, gadgetId, gadget);
view.setGadget(gadgetId, gadget);
view.updateGadget(null);
return view;
}
/**
* Called to create the GadgetHostView. Override to return a custom subclass if you
* need it. {@more}
*/
protected GadgetHostView onCreateView(Context context, int gadgetId, GadgetInfo gadget) {
return new GadgetHostView(context);
}
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright (C) 2008 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 android.gadget;
import android.content.Context;
import android.content.pm.PackageManager;
import android.gadget.GadgetInfo;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
public class GadgetHostView extends FrameLayout {
static final String TAG = "GadgetHostView";
// When we're inflating the initialLayout for a gadget, we only allow
// views that are allowed in RemoteViews.
static final LayoutInflater.Filter sInflaterFilter = new LayoutInflater.Filter() {
public boolean onLoadClass(Class clazz) {
return clazz.isAnnotationPresent(RemoteViews.RemoteView.class);
}
};
int mGadgetId;
GadgetInfo mInfo;
View mContentView;
public GadgetHostView(Context context) {
super(context);
}
public void setGadget(int gadgetId, GadgetInfo info) {
if (mInfo != null) {
// TODO: remove the old view, or whatever
}
mGadgetId = gadgetId;
mInfo = info;
}
public void updateGadget(RemoteViews remoteViews) {
Context context = getContext();
View contentView = null;
Exception exception = null;
try {
if (remoteViews == null) {
// there is no remoteViews (yet), so use the initial layout
Context theirContext = context.createPackageContext(mInfo.provider.getPackageName(),
0);
LayoutInflater inflater = (LayoutInflater)theirContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
inflater = inflater.cloneInContext(theirContext);
inflater.setFilter(sInflaterFilter);
contentView = inflater.inflate(mInfo.initialLayout, this, false);
} else {
// use the RemoteViews
contentView = remoteViews.apply(mContext, this);
}
}
catch (PackageManager.NameNotFoundException e) {
exception = e;
}
catch (RuntimeException e) {
exception = e;
}
if (contentView == null) {
Log.w(TAG, "Error inflating gadget " + mInfo, exception);
// TODO: Should we throw an exception here for the host activity to catch?
// Maybe we should show a generic error widget.
TextView tv = new TextView(context);
tv.setText("Error inflating gadget");
contentView = tv;
}
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT);
mContentView = contentView;
this.addView(contentView, lp);
// TODO: do an animation (maybe even one provided by the gadget).
}
}

View File

@@ -1,25 +1,19 @@
/*
* Copyright (C) 2008, The Android Open Source Project
* Copyright (c) 2007, 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
* 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
* 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
* 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 android.bluetooth;
package android.gadget;
/**
* {@hide}
*/
oneway interface IBluetoothHeadsetCallback
{
void onConnectHeadsetResult(in String address, int resultCode);
}
parcelable GadgetInfo;

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2006 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 android.gadget;
import android.os.Parcel;
import android.os.Parcelable;
import android.content.ComponentName;
/**
* Describes the meta data for an installed gadget.
*/
public class GadgetInfo implements Parcelable {
/**
* Identity of this gadget component. This component should be a {@link
* android.content.BroadcastReceiver}, and it will be sent the Gadget intents
* {@link android.gadget as described in the gadget package documentation}.
*/
public ComponentName provider;
/**
* Minimum width of the gadget, in dp.
*/
public int minWidth;
/**
* Minimum height of the gadget, in dp.
*/
public int minHeight;
/**
* How often, in milliseconds, that this gadget wants to be updated.
* The gadget manager may place a limit on how often a gadget is updated.
*/
public int updatePeriodMillis;
/**
* The resource id of the initial layout for this gadget. This should be
* displayed until the RemoteViews for the gadget is available.
*/
public int initialLayout;
/**
* The activity to launch that will configure the gadget.
*/
public ComponentName configure;
public GadgetInfo() {
}
/**
* Unflatten the GadgetInfo from a parcel.
*/
public GadgetInfo(Parcel in) {
if (0 != in.readInt()) {
this.provider = new ComponentName(in);
}
this.minWidth = in.readInt();
this.minHeight = in.readInt();
this.updatePeriodMillis = in.readInt();
this.initialLayout = in.readInt();
if (0 != in.readInt()) {
this.configure = new ComponentName(in);
}
}
public void writeToParcel(android.os.Parcel out, int flags) {
if (this.provider != null) {
out.writeInt(1);
this.provider.writeToParcel(out, flags);
} else {
out.writeInt(0);
}
out.writeInt(this.minWidth);
out.writeInt(this.minHeight);
out.writeInt(this.updatePeriodMillis);
out.writeInt(this.initialLayout);
if (this.configure != null) {
out.writeInt(1);
this.configure.writeToParcel(out, flags);
} else {
out.writeInt(0);
}
}
public int describeContents() {
return 0;
}
/**
* Parcelable.Creator that instantiates GadgetInfo objects
*/
public static final Parcelable.Creator<GadgetInfo> CREATOR
= new Parcelable.Creator<GadgetInfo>()
{
public GadgetInfo createFromParcel(Parcel parcel)
{
return new GadgetInfo(parcel);
}
public GadgetInfo[] newArray(int size)
{
return new GadgetInfo[size];
}
};
public String toString() {
return "GadgetInfo(provider=" + this.provider + ")";
}
}

View File

@@ -0,0 +1,170 @@
/*
* Copyright (C) 2006 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 android.gadget;
import android.content.ComponentName;
import android.content.Context;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.util.Log;
import android.widget.RemoteViews;
import com.android.internal.gadget.IGadgetService;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.WeakHashMap;
public class GadgetManager {
static final String TAG = "GadgetManager";
/**
* Send this when you want to pick a gadget to display.
*
* <p>
* The system will respond with an onActivityResult call with the following extras in
* the intent:
* <ul>
* <li><b>gadgetId</b></li>
* <li><b>gadgetId</b></li>
* <li><b>gadgetId</b></li>
* </ul>
* TODO: Add constants for these.
* TODO: Where does this go?
*/
public static final String GADGET_PICK_ACTION = "android.gadget.action.PICK_GADGET";
public static final String EXTRA_GADGET_ID = "gadgetId";
/**
* Sent when it is time to update your gadget.
*/
public static final String GADGET_UPDATE_ACTION = "android.gadget.GADGET_UPDATE";
/**
* Sent when the gadget is added to a host for the first time. TODO: Maybe we don't want this.
*/
public static final String GADGET_ENABLE_ACTION = "android.gadget.GADGET_ENABLE";
/**
* Sent when the gadget is removed from the last host. TODO: Maybe we don't want this.
*/
public static final String GADGET_DISABLE_ACTION = "android.gadget.GADGET_DISABLE";
static WeakHashMap<Context, WeakReference<GadgetManager>> sManagerCache = new WeakHashMap();
static IGadgetService sService;
Context mContext;
public static GadgetManager getInstance(Context context) {
synchronized (sManagerCache) {
if (sService == null) {
IBinder b = ServiceManager.getService(Context.GADGET_SERVICE);
sService = IGadgetService.Stub.asInterface(b);
}
WeakReference<GadgetManager> ref = sManagerCache.get(context);
GadgetManager result = null;
if (ref != null) {
result = ref.get();
}
if (result == null) {
result = new GadgetManager(context);
sManagerCache.put(context, new WeakReference(result));
}
return result;
}
}
private GadgetManager(Context context) {
mContext = context;
}
/**
* Call this with the new RemoteViews for your gadget whenever you need to.
*
* <p>
* This method will only work when called from the uid that owns the gadget provider.
*
* @param gadgetId The gadget instance for which to set the RemoteViews.
* @param views The RemoteViews object to show.
*/
public void updateGadget(int gadgetId, RemoteViews views) {
}
/**
* Return a list of the gadgets that are currently installed.
*/
public List<GadgetInfo> getAvailableGadgets() {
return null;
}
/**
* Get the available info about the gadget. If the gadgetId has not been bound yet,
* this method will return null.
*
* TODO: throws GadgetNotFoundException ??? if not valid
*/
public GadgetInfo getGadgetInfo(int gadgetId) {
try {
return sService.getGadgetInfo(gadgetId);
}
catch (RemoteException e) {
throw new RuntimeException("system server dead?", e);
}
}
/**
* Get a gadgetId for a host in the calling process.
*
* @return a gadgetId
*/
public int allocateGadgetId(String hostPackage) {
try {
return sService.allocateGadgetId(hostPackage);
}
catch (RemoteException e) {
throw new RuntimeException("system server dead?", e);
}
}
/**
* Delete the gadgetId. Same as removeGadget on GadgetHost.
*/
public void deleteGadgetId(int gadgetId) {
try {
sService.deleteGadgetId(gadgetId);
}
catch (RemoteException e) {
throw new RuntimeException("system server dead?", e);
}
}
/**
* Set the component for a given gadgetId. You need the GADGET_LIST permission.
*/
public void bindGadgetId(int gadgetId, ComponentName provider) {
try {
sService.bindGadgetId(gadgetId, provider);
}
catch (RemoteException e) {
throw new RuntimeException("system server dead?", e);
}
}
}

View File

@@ -0,0 +1,4 @@
<body>
@hide
</body>

View File

@@ -55,6 +55,7 @@ public class Camera {
private PreviewCallback mPreviewCallback;
private AutoFocusCallback mAutoFocusCallback;
private ErrorCallback mErrorCallback;
private boolean mOneShot;
/**
* Returns a new Camera object.
@@ -198,9 +199,25 @@ public class Camera {
*/
public final void setPreviewCallback(PreviewCallback cb) {
mPreviewCallback = cb;
setHasPreviewCallback(cb != null);
mOneShot = false;
setHasPreviewCallback(cb != null, false);
}
private native final void setHasPreviewCallback(boolean installed);
/**
* Installs a callback to retrieve a single preview frame, after which the
* callback is cleared.
*
* @param cb A callback object that receives a copy of the preview frame.
*/
public final void setOneShotPreviewCallback(PreviewCallback cb) {
if (cb != null) {
mPreviewCallback = cb;
mOneShot = true;
setHasPreviewCallback(true, true);
}
}
private native final void setHasPreviewCallback(boolean installed, boolean oneshot);
private class EventHandler extends Handler
{
@@ -230,8 +247,12 @@ public class Camera {
return;
case PREVIEW_CALLBACK:
if (mPreviewCallback != null)
if (mPreviewCallback != null) {
mPreviewCallback.onPreviewFrame((byte[])msg.obj, mCamera);
if (mOneShot) {
mPreviewCallback = null;
}
}
return;
case AUTOFOCUS_CALLBACK:

View File

@@ -33,6 +33,8 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
@@ -197,6 +199,7 @@ public class InputMethodService extends AbstractInputMethodService {
EditorInfo mInputEditorInfo;
boolean mShowInputRequested;
boolean mLastShowInputRequested;
boolean mShowCandidatesRequested;
boolean mFullscreenApplied;
@@ -257,6 +260,8 @@ public class InputMethodService extends AbstractInputMethodService {
public void bindInput(InputBinding binding) {
mInputBinding = binding;
mInputConnection = binding.getConnection();
if (DEBUG) Log.v(TAG, "bindInput(): binding=" + binding
+ " ic=" + mInputConnection);
onBindInput();
}
@@ -264,17 +269,22 @@ public class InputMethodService extends AbstractInputMethodService {
* Clear the current input binding.
*/
public void unbindInput() {
if (DEBUG) Log.v(TAG, "unbindInput(): binding=" + mInputBinding
+ " ic=" + mInputConnection);
onUnbindInput();
mInputStarted = false;
mInputBinding = null;
mInputConnection = null;
}
public void startInput(EditorInfo attribute) {
if (DEBUG) Log.v(TAG, "startInput(): editor=" + attribute);
doStartInput(attribute, false);
}
public void restartInput(EditorInfo attribute) {
doStartInput(attribute, false);
if (DEBUG) Log.v(TAG, "restartInput(): editor=" + attribute);
doStartInput(attribute, true);
}
/**
@@ -305,6 +315,7 @@ public class InputMethodService extends AbstractInputMethodService {
if (!isEnabled()) {
return;
}
if (DEBUG) Log.v(TAG, "finishInput() in " + this);
onFinishInput();
mInputStarted = false;
}
@@ -455,7 +466,7 @@ public class InputMethodService extends AbstractInputMethodService {
mIsInputViewShown = false;
mExtractFrame.setVisibility(View.GONE);
mCandidatesFrame.setVisibility(View.GONE);
mCandidatesFrame.setVisibility(View.INVISIBLE);
mInputFrame.setVisibility(View.GONE);
}
@@ -468,6 +479,29 @@ public class InputMethodService extends AbstractInputMethodService {
}
}
/**
* Take care of handling configuration changes. Subclasses of
* InputMethodService generally don't need to deal directly with
* this on their own; the standard implementation here takes care of
* regenerating the input method UI as a result of the configuration
* change, so you can rely on your {@link #onCreateInputView} and
* other methods being called as appropriate due to a configuration change.
*/
@Override public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
boolean visible = mWindowVisible;
boolean showingInput = mShowInputRequested;
boolean showingCandidates = mShowCandidatesRequested;
initViews();
if (visible) {
if (showingCandidates) {
setCandidatesViewShown(true);
}
showWindow(showingInput);
}
}
/**
* Implement to return our standard {@link InputMethodImpl}. Subclasses
* can override to provide their own customized version.
@@ -492,6 +526,27 @@ public class InputMethodService extends AbstractInputMethodService {
return mWindow;
}
/**
* Return the maximum width, in pixels, available the input method.
* Input methods are positioned at the bottom of the screen and, unless
* running in fullscreen, will generally want to be as short as possible
* so should compute their height based on their contents. However, they
* can stretch as much as needed horizontally. The function returns to
* you the maximum amount of space available horizontally, which you can
* use if needed for UI placement.
*
* <p>In many cases this is not needed, you can just rely on the normal
* view layout mechanisms to position your views within the full horizontal
* space given to the input method.
*
* <p>Note that this value can change dynamically, in particular when the
* screen orientation changes.
*/
public int getMaxWidth() {
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
return wm.getDefaultDisplay().getWidth();
}
/**
* Return the currently active InputBinding for the input method, or
* null if there is none.
@@ -525,12 +580,19 @@ public class InputMethodService extends AbstractInputMethodService {
* is currently running in fullscreen mode.
*/
public void updateFullscreenMode() {
boolean isFullscreen = onEvaluateFullscreenMode();
boolean isFullscreen = mShowInputRequested && onEvaluateFullscreenMode();
boolean changed = mLastShowInputRequested != mShowInputRequested;
if (mIsFullscreen != isFullscreen || !mFullscreenApplied) {
changed = true;
mIsFullscreen = isFullscreen;
mFullscreenApplied = true;
mWindow.getWindow().setBackgroundDrawable(
onCreateBackgroundDrawable());
Drawable bg = onCreateBackgroundDrawable();
if (bg == null) {
// We need to give the window a real drawable, so that it
// correctly sets its mode.
bg = getResources().getDrawable(android.R.color.transparent);
}
mWindow.getWindow().setBackgroundDrawable(bg);
mExtractFrame.setVisibility(isFullscreen ? View.VISIBLE : View.GONE);
if (isFullscreen) {
if (mExtractView == null) {
@@ -540,11 +602,39 @@ public class InputMethodService extends AbstractInputMethodService {
}
}
startExtractingText();
mWindow.getWindow().setLayout(FILL_PARENT, FILL_PARENT);
} else {
mWindow.getWindow().setLayout(WRAP_CONTENT, WRAP_CONTENT);
}
}
if (changed) {
onConfigureWindow(mWindow.getWindow(), isFullscreen,
!mShowInputRequested);
mLastShowInputRequested = mShowInputRequested;
}
}
/**
* Update the given window's parameters for the given mode. This is called
* when the window is first displayed and each time the fullscreen or
* candidates only mode changes.
*
* <p>The default implementation makes the layout for the window
* FILL_PARENT x FILL_PARENT when in fullscreen mode, and
* FILL_PARENT x WRAP_CONTENT when in non-fullscreen mode.
*
* @param win The input method's window.
* @param isFullscreen If true, the window is running in fullscreen mode
* and intended to cover the entire application display.
* @param isCandidatesOnly If true, the window is only showing the
* candidates view and none of the rest of its UI. This is mutually
* exclusive with fullscreen mode.
*/
public void onConfigureWindow(Window win, boolean isFullscreen,
boolean isCandidatesOnly) {
if (isFullscreen) {
mWindow.getWindow().setLayout(FILL_PARENT, FILL_PARENT);
} else {
mWindow.getWindow().setLayout(FILL_PARENT, WRAP_CONTENT);
}
}
/**
@@ -607,7 +697,7 @@ public class InputMethodService extends AbstractInputMethodService {
* is currently shown.
*/
public void updateInputViewShown() {
boolean isShown = onEvaluateInputViewShown();
boolean isShown = mShowInputRequested && onEvaluateInputViewShown();
if (mIsInputViewShown != isShown && mWindowVisible) {
mIsInputViewShown = isShown;
mInputFrame.setVisibility(isShown ? View.VISIBLE : View.GONE);
@@ -650,18 +740,18 @@ public class InputMethodService extends AbstractInputMethodService {
public void setCandidatesViewShown(boolean shown) {
if (mShowCandidatesRequested != shown) {
mCandidatesFrame.setVisibility(shown ? View.VISIBLE : View.INVISIBLE);
if (!mShowInputRequested) {
// If we are being asked to show the candidates view while the app
// has not asked for the input view to be shown, then we need
// to update whether the window is shown.
if (shown) {
showWindow(false);
} else {
hideWindow();
}
}
mShowCandidatesRequested = shown;
}
if (!mShowInputRequested && mWindowVisible != shown) {
// If we are being asked to show the candidates view while the app
// has not asked for the input view to be shown, then we need
// to update whether the window is shown.
if (shown) {
showWindow(false);
} else {
hideWindow();
}
}
}
public void setStatusIcon(int iconResId) {
@@ -729,7 +819,7 @@ public class InputMethodService extends AbstractInputMethodService {
* Called by the framework to create a Drawable for the background of
* the input method window. May return null for no background. The default
* implementation returns a non-null standard background only when in
* fullscreen mode.
* fullscreen mode. This is called each time the fullscreen mode changes.
*/
public Drawable onCreateBackgroundDrawable() {
if (isFullscreenMode()) {
@@ -789,22 +879,6 @@ public class InputMethodService extends AbstractInputMethodService {
public void onStartInputView(EditorInfo info, boolean restarting) {
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
boolean visible = mWindowVisible;
boolean showingInput = mShowInputRequested;
boolean showingCandidates = mShowCandidatesRequested;
initViews();
if (visible) {
if (showingCandidates) {
setCandidatesViewShown(true);
}
showWindow(showingInput);
}
}
/**
* The system has decided that it may be time to show your input method.
* This is called due to a corresponding call to your
@@ -837,17 +911,17 @@ public class InputMethodService extends AbstractInputMethodService {
boolean wasVisible = mWindowVisible;
mWindowVisible = true;
if (!mShowInputRequested) {
doShowInput = true;
mShowInputRequested = true;
if (showInput) {
doShowInput = true;
mShowInputRequested = true;
}
} else {
showInput = true;
}
if (doShowInput) {
if (DEBUG) Log.v(TAG, "showWindow: updating UI");
updateFullscreenMode();
updateInputViewShown();
}
if (DEBUG) Log.v(TAG, "showWindow: updating UI");
updateFullscreenMode();
updateInputViewShown();
if (!mWindowAdded || !mWindowCreated) {
mWindowAdded = true;
@@ -885,13 +959,44 @@ public class InputMethodService extends AbstractInputMethodService {
}
}
/**
* Called when a new client has bound to the input method. This
* may be followed by a series of {@link #onStartInput(EditorInfo, boolean)}
* and {@link #onFinishInput()} calls as the user navigates through its
* UI. Upon this call you know that {@link #getCurrentInputBinding}
* and {@link #getCurrentInputConnection} return valid objects.
*/
public void onBindInput() {
}
/**
* Called when the previous bound client is no longer associated
* with the input method. After returning {@link #getCurrentInputBinding}
* and {@link #getCurrentInputConnection} will no longer return
* valid objects.
*/
public void onUnbindInput() {
}
/**
* Called to inform the input method that text input has started in an
* editor. You should use this callback to initialize the state of your
* input to match the state of the editor given to it.
*
* @param attribute The attributes of the editor that input is starting
* in.
* @param restarting Set to true if input is restarting in the same
* editor such as because the application has changed the text in
* the editor. Otherwise will be false, indicating this is a new
* session with the editor.
*/
public void onStartInput(EditorInfo attribute, boolean restarting) {
}
void doStartInput(EditorInfo attribute, boolean restarting) {
if (mInputStarted && !restarting) {
onFinishInput();
}
mInputStarted = true;
mInputEditorInfo = attribute;
onStartInput(attribute, restarting);
@@ -903,6 +1008,13 @@ public class InputMethodService extends AbstractInputMethodService {
}
}
/**
* Called to inform the input method that text input has finished in
* the last editor. At this point there may be a call to
* {@link #onStartInput(EditorInfo, boolean)} to perform input in a
* new editor, or the input method may be left idle. This method is
* <em>not</em> called when input restarts in the same editor.
*/
public void onFinishInput() {
}

View File

@@ -1740,12 +1740,12 @@ public final class Settings {
*/
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/secure");
/**
* Whether ADB is enabled.
*/
public static final String ADB_ENABLED = "adb_enabled";
/**
* Setting to allow mock locations and location provider status to be injected into the
* LocationManager service for testing purposes during application development. These
@@ -1753,7 +1753,7 @@ public final class Settings {
* by network, gps, or other location providers.
*/
public static final String ALLOW_MOCK_LOCATION = "mock_location";
/**
* The Android ID (a unique 64-bit value) as a hex string.
* Identical to that obtained by calling
@@ -1761,24 +1761,40 @@ public final class Settings {
* so you can get it without binding to a service.
*/
public static final String ANDROID_ID = "android_id";
/**
* Whether bluetooth is enabled/disabled
* 0=disabled. 1=enabled.
*/
public static final String BLUETOOTH_ON = "bluetooth_on";
/**
* Get the key that retrieves a bluetooth headset's priority.
* @hide
*/
public static final String getBluetoothHeadsetPriorityKey(String address) {
return ("bluetooth_headset_priority_" + address.toUpperCase());
}
/**
* Get the key that retrieves a bluetooth a2dp sink's priority.
* @hide
*/
public static final String getBluetoothA2dpSinkPriorityKey(String address) {
return ("bluetooth_a2dp_sink_priority_" + address.toUpperCase());
}
/**
* Whether or not data roaming is enabled. (0 = false, 1 = true)
*/
public static final String DATA_ROAMING = "data_roaming";
/**
* Setting to record the input method used by default, holding the ID
* of the desired method.
*/
public static final String DEFAULT_INPUT_METHOD = "default_input_method";
/**
* Whether the device has been provisioned (0 = false, 1 = true)
*/
@@ -1953,7 +1969,13 @@ public final class Settings {
* Whether the Wi-Fi watchdog is enabled.
*/
public static final String WIFI_WATCHDOG_ON = "wifi_watchdog_on";
/**
* A comma-separated list of SSIDs for which the Wi-Fi watchdog should be enabled.
* @hide pending API council
*/
public static final String WIFI_WATCHDOG_WATCH_LIST = "wifi_watchdog_watch_list";
/**
* The number of pings to test if an access point is a good connection.
*/

View File

@@ -0,0 +1,127 @@
/*
* Copyright (C) 2008 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 android.provider;
import java.util.Locale;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.net.Uri;
import android.text.TextUtils;
/**
*
* @hide Pending API council approval
*/
public class UserDictionary {
public static final String AUTHORITY = "user_dictionary";
/**
* The content:// style URL for this provider
*/
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY);
/**
* Contains the user defined words.
* @hide Pending API council approval
*/
public static class Words implements BaseColumns {
/**
* The content:// style URL for this table
*/
public static final Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/words");
/**
* The MIME type of {@link #CONTENT_URI} providing a directory of words.
*/
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.userword";
/**
* The MIME type of a {@link #CONTENT_URI} sub-directory of a single word.
*/
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.userword";
public static final String _ID = BaseColumns._ID;
/**
* The word column.
* <p>TYPE: TEXT</p>
*/
public static final String WORD = "word";
/**
* The frequency column. A value between 1 and 255.
* <p>TYPE: INTEGER</p>
*/
public static final String FREQUENCY = "frequency";
/**
* The locale that this word belongs to. Null if it pertains to all
* locales. Locale is a 5 letter string such as <pre>en_US</pre>.
* <p>TYPE: TEXT</p>
*/
public static final String LOCALE = "locale";
/**
* The uid of the application that inserted the word.
* <p>TYPE: INTEGER</p>
*/
public static final String APP_ID = "appid";
public static final int LOCALE_TYPE_ALL = 0;
public static final int LOCALE_TYPE_CURRENT = 1;
/**
* Sort by descending order of frequency.
*/
public static final String DEFAULT_SORT_ORDER = FREQUENCY + " DESC";
public static void addWord(Context context, String word,
int frequency, int localeType) {
final ContentResolver resolver = context.getContentResolver();
if (TextUtils.isEmpty(word) || localeType < 0 || localeType > 1) {
return;
}
if (frequency < 0) frequency = 0;
if (frequency > 255) frequency = 255;
String locale = null;
// TODO: Verify if this is the best way to get the current locale
if (localeType == LOCALE_TYPE_CURRENT) {
locale = Locale.getDefault().toString();
}
ContentValues values = new ContentValues(4);
values.put(WORD, word);
values.put(FREQUENCY, frequency);
values.put(LOCALE, locale);
values.put(APP_ID, 0); // TODO: Get App UID
Uri result = resolver.insert(CONTENT_URI, values);
// It's ok if the insert doesn't succeed because the word
// already exists.
}
}
}

View File

@@ -35,6 +35,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.media.AudioManager;
import android.os.Binder;
import android.provider.Settings;
import android.util.Log;
import java.io.FileDescriptor;
@@ -83,6 +84,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
mIntentFilter = new IntentFilter(BluetoothIntent.ENABLED_ACTION);
mIntentFilter.addAction(BluetoothIntent.DISABLED_ACTION);
mIntentFilter.addAction(BluetoothIntent.BONDING_CREATED_ACTION);
mIntentFilter.addAction(BluetoothIntent.BONDING_REMOVED_ACTION);
mContext.registerReceiver(mReceiver, mIntentFilter);
if (device.isEnabled()) {
@@ -103,10 +106,15 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
String address = intent.getStringExtra(BluetoothIntent.ADDRESS);
if (action.equals(BluetoothIntent.ENABLED_ACTION)) {
onBluetoothEnable();
} else if (action.equals(BluetoothIntent.DISABLED_ACTION)) {
onBluetoothDisable();
} else if (action.equals(BluetoothIntent.BONDING_CREATED_ACTION)) {
setSinkPriority(address, BluetoothA2dp.PRIORITY_AUTO);
} else if (action.equals(BluetoothIntent.BONDING_REMOVED_ACTION)) {
setSinkPriority(address, BluetoothA2dp.PRIORITY_OFF);
}
}
};
@@ -145,7 +153,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
if (path == null) {
return BluetoothError.ERROR;
}
SinkState sink = mAudioDevices.get(path);
int state = BluetoothA2dp.STATE_DISCONNECTED;
if (sink != null) {
@@ -159,8 +167,8 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
case BluetoothA2dp.STATE_CONNECTING:
return BluetoothError.SUCCESS;
}
// State is DISCONNECTED
// State is DISCONNECTED
if (!connectSinkNative(path)) {
return BluetoothError.ERROR;
}
@@ -189,7 +197,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
return BluetoothError.SUCCESS;
}
// State is CONNECTING or CONNECTED or PLAYING
// State is CONNECTING or CONNECTED or PLAYING
if (!disconnectSinkNative(path)) {
return BluetoothError.ERROR;
} else {
@@ -229,16 +237,37 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
return BluetoothA2dp.STATE_DISCONNECTED;
}
public synchronized void onHeadsetCreated(String path) {
public synchronized int getSinkPriority(String address) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return BluetoothError.ERROR;
}
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.getBluetoothA2dpSinkPriorityKey(address),
BluetoothA2dp.PRIORITY_OFF);
}
public synchronized int setSinkPriority(String address, int priority) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_ADMIN_PERM,
"Need BLUETOOTH_ADMIN permission");
if (!BluetoothDevice.checkBluetoothAddress(address)) {
return BluetoothError.ERROR;
}
return Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.getBluetoothA2dpSinkPriorityKey(address), priority) ?
BluetoothError.SUCCESS : BluetoothError.ERROR;
}
private synchronized void onHeadsetCreated(String path) {
updateState(path, BluetoothA2dp.STATE_DISCONNECTED);
}
public synchronized void onHeadsetRemoved(String path) {
private synchronized void onHeadsetRemoved(String path) {
if (mAudioDevices == null) return;
mAudioDevices.remove(path);
}
public synchronized void onSinkConnected(String path) {
private synchronized void onSinkConnected(String path) {
if (mAudioDevices == null) return;
// bluez 3.36 quietly disconnects the previous sink when a new sink
// is connected, so we need to mark all previously connected sinks as
@@ -258,16 +287,16 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
updateState(path, BluetoothA2dp.STATE_CONNECTED);
}
public synchronized void onSinkDisconnected(String path) {
private synchronized void onSinkDisconnected(String path) {
mAudioManager.setBluetoothA2dpOn(false);
updateState(path, BluetoothA2dp.STATE_DISCONNECTED);
}
public synchronized void onSinkPlaying(String path) {
private synchronized void onSinkPlaying(String path) {
updateState(path, BluetoothA2dp.STATE_PLAYING);
}
public synchronized void onSinkStopped(String path) {
private synchronized void onSinkStopped(String path) {
updateState(path, BluetoothA2dp.STATE_CONNECTED);
}
@@ -307,7 +336,7 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
if (state != prevState) {
if (DBG) log("state " + address + " (" + path + ") " + prevState + "->" + state);
Intent intent = new Intent(BluetoothA2dp.SINK_STATE_CHANGED_ACTION);
intent.putExtra(BluetoothIntent.ADDRESS, address);
intent.putExtra(BluetoothA2dp.SINK_PREVIOUS_STATE, prevState);
@@ -339,5 +368,4 @@ public class BluetoothA2dpService extends IBluetoothA2dp.Stub {
private synchronized native boolean connectSinkNative(String path);
private synchronized native boolean disconnectSinkNative(String path);
private synchronized native boolean isSinkConnectedNative(String path);
}

View File

@@ -367,6 +367,35 @@ public final class Recognizer {
SR_RecognizerStop(mRecognizer);
SR_RecognizerDeactivateRule(mRecognizer, mActiveGrammar.mGrammar, "trash");
}
/**
* Reset the acoustic state vectorto it's default value.
*
* @hide
*/
public void resetAcousticState() {
SR_AcousticStateReset(mRecognizer);
}
/**
* Set the acoustic state vector.
* @param state String containing the acoustic state vector.
*
* @hide
*/
public void setAcousticState(String state) {
SR_AcousticStateSet(mRecognizer, state);
}
/**
* Get the acoustic state vector.
* @return String containing the acoustic state vector.
*
* @hide
*/
public String getAcousticState() {
return SR_AcousticStateGet(mRecognizer);
}
/**
* Clean up resources.
@@ -572,6 +601,9 @@ public final class Recognizer {
return "EVENT_" + event;
}
//
// SR_Recognizer methods
//
private static native void SR_RecognizerStart(int recognizer);
private static native void SR_RecognizerStop(int recognizer);
private static native int SR_RecognizerCreate();
@@ -615,6 +647,14 @@ public final class Recognizer {
private static native boolean SR_RecognizerIsSignalTooFewSamples(int recognizer);
private static native boolean SR_RecognizerIsSignalTooManySamples(int recognizer);
// private static native void SR_Recognizer_Change_Sample_Rate (size_t new_sample_rate);
//
// SR_AcousticState native methods
//
private static native void SR_AcousticStateReset(int recognizer);
private static native void SR_AcousticStateSet(int recognizer, String state);
private static native String SR_AcousticStateGet(int recognizer);
//

View File

@@ -263,5 +263,12 @@ public class WaveHeader {
out.write(val >> 0);
out.write(val >> 8);
}
@Override
public String toString() {
return String.format(
"WaveHeader format=%d numChannels=%d sampleRate=%d bitsPerSample=%d numBytes=%d",
mFormat, mNumChannels, mSampleRate, mBitsPerSample, mNumBytes);
}
}

View File

@@ -117,6 +117,7 @@ public final class ViewRoot extends Handler implements ViewParent,
View mView;
View mFocusedView;
View mRealFocusedView; // this is not set to null in touch mode
int mViewVisibility;
boolean mAppVisible = true;
@@ -971,9 +972,19 @@ public final class ViewRoot extends Handler implements ViewParent,
if (mFirst) {
// handle first focus request
if (mView != null && !mView.hasFocus()) {
mView.requestFocus(View.FOCUS_FORWARD);
mFocusedView = mView.findFocus();
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: mView.hasFocus()="
+ mView.hasFocus());
if (mView != null) {
if (!mView.hasFocus()) {
mView.requestFocus(View.FOCUS_FORWARD);
mFocusedView = mRealFocusedView = mView.findFocus();
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: requested focused view="
+ mFocusedView);
} else {
mRealFocusedView = mView.findFocus();
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "First: existing focused view="
+ mRealFocusedView);
}
}
}
@@ -1214,13 +1225,16 @@ public final class ViewRoot extends Handler implements ViewParent,
// requestChildRectangleOnScreen() call (in which case 'rectangle'
// is non-null and we just want to scroll to whatever that
// rectangle is).
View focus = mFocusedView;
View focus = mRealFocusedView;
if (focus != mLastScrolledFocus) {
// If the focus has changed, then ignore any requests to scroll
// to a rectangle; first we want to make sure the entire focus
// view is visible.
rectangle = null;
}
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Eval scroll: focus=" + focus
+ " rectangle=" + rectangle + " ci=" + ci
+ " vi=" + vi);
if (focus == mLastScrolledFocus && !mScrollMayChange
&& rectangle == null) {
// Optimization: if the focus hasn't changed since last
@@ -1234,6 +1248,7 @@ public final class ViewRoot extends Handler implements ViewParent,
// a pan so it can be seen.
mLastScrolledFocus = focus;
mScrollMayChange = false;
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Need to scroll?");
// Try to find the rectangle from the focus view.
if (focus.getGlobalVisibleRect(mVisRect, null)) {
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Root w="
@@ -1307,7 +1322,9 @@ public final class ViewRoot extends Handler implements ViewParent,
mAttachInfo.mTreeObserver.dispatchOnGlobalFocusChange(mFocusedView, focused);
scheduleTraversals();
}
mFocusedView = focused;
mFocusedView = mRealFocusedView = focused;
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Request child focus: focus now "
+ mFocusedView);
}
public void clearChildFocus(View child) {
@@ -1315,7 +1332,8 @@ public final class ViewRoot extends Handler implements ViewParent,
View oldFocus = mFocusedView;
mFocusedView = null;
if (DEBUG_INPUT_RESIZE) Log.v(TAG, "Clearing child focus");
mFocusedView = mRealFocusedView = null;
if (mView != null && !mView.hasFocus()) {
// If a view gets the focus, the listener will be invoked from requestChildFocus()
if (!mView.requestFocus(View.FOCUS_FORWARD)) {

View File

@@ -800,7 +800,7 @@ public final class InputMethodManager {
try {
if (DEBUG) Log.v(TAG, "START INPUT: " + view + " ic="
+ ic + " tba=" + tba);
+ ic + " tba=" + tba + " initial=" + initial);
InputBindResult res = mService.startInput(mClient, tba, initial,
mCurMethod == null);
if (DEBUG) Log.v(TAG, "Starting input: Bind result=" + res);
@@ -848,6 +848,9 @@ public final class InputMethodManager {
synchronized (mH) {
if (DEBUG) Log.v(TAG, "focusIn: " + view);
// Okay we have a new view that is being served.
if (mServedView != view) {
mCurrentTextBoxAttribute = null;
}
mServedView = view;
mCompletions = null;
mServedConnecting = true;

View File

@@ -16,8 +16,10 @@
package android.webkit;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
@@ -30,7 +32,14 @@ import android.os.SystemClock;
import android.util.Config;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import com.android.internal.R;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
/**
@@ -376,12 +385,24 @@ class CallbackProxy extends Handler {
case JS_ALERT:
if (mWebChromeClient != null) {
JsResult res = (JsResult) msg.obj;
final JsResult res = (JsResult) msg.obj;
String message = msg.getData().getString("message");
String url = msg.getData().getString("url");
if (!mWebChromeClient.onJsAlert(mWebView, url, message,
res)) {
res.handleDefault();
res)) {
new AlertDialog.Builder(mContext)
.setTitle(getJsDialogTitle(url))
.setMessage(message)
.setPositiveButton(R.string.ok,
new AlertDialog.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
res.confirm();
}
})
.setCancelable(false)
.show();
}
res.setReady();
}
@@ -389,12 +410,29 @@ class CallbackProxy extends Handler {
case JS_CONFIRM:
if (mWebChromeClient != null) {
JsResult res = (JsResult) msg.obj;
final JsResult res = (JsResult) msg.obj;
String message = msg.getData().getString("message");
String url = msg.getData().getString("url");
if (!mWebChromeClient.onJsConfirm(mWebView, url, message,
res)) {
res.handleDefault();
res)) {
new AlertDialog.Builder(mContext)
.setTitle(getJsDialogTitle(url))
.setMessage(message)
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
res.confirm();
}})
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
res.cancel();
}})
.show();
}
// Tell the JsResult that it is ready for client
// interaction.
@@ -404,13 +442,49 @@ class CallbackProxy extends Handler {
case JS_PROMPT:
if (mWebChromeClient != null) {
JsPromptResult res = (JsPromptResult) msg.obj;
final JsPromptResult res = (JsPromptResult) msg.obj;
String message = msg.getData().getString("message");
String defaultVal = msg.getData().getString("default");
String url = msg.getData().getString("url");
if (!mWebChromeClient.onJsPrompt(mWebView, url, message,
defaultVal, res)) {
res.handleDefault();
final LayoutInflater factory = LayoutInflater
.from(mContext);
final View view = factory.inflate(R.layout.js_prompt,
null);
final EditText v = (EditText) view
.findViewById(R.id.value);
v.setText(defaultVal);
((TextView) view.findViewById(R.id.message))
.setText(message);
new AlertDialog.Builder(mContext)
.setTitle(getJsDialogTitle(url))
.setView(view)
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int whichButton) {
res.confirm(v.getText()
.toString());
}
})
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int whichButton) {
res.cancel();
}
})
.setOnCancelListener(
new DialogInterface.OnCancelListener() {
public void onCancel(
DialogInterface dialog) {
res.cancel();
}
})
.show();
}
// Tell the JsResult that it is ready for client
// interaction.
@@ -420,12 +494,32 @@ class CallbackProxy extends Handler {
case JS_UNLOAD:
if (mWebChromeClient != null) {
JsResult res = (JsResult) msg.obj;
final JsResult res = (JsResult) msg.obj;
String message = msg.getData().getString("message");
String url = msg.getData().getString("url");
if (!mWebChromeClient.onJsBeforeUnload(mWebView, url,
message, res)) {
res.handleDefault();
message, res)) {
final String m = mContext.getString(
R.string.js_dialog_before_unload, message);
new AlertDialog.Builder(mContext)
.setMessage(m)
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
res.confirm();
}
})
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(
DialogInterface dialog,
int which) {
res.cancel();
}
})
.show();
}
res.setReady();
}
@@ -468,6 +562,24 @@ class CallbackProxy extends Handler {
sendMessage(obtainMessage(SWITCH_OUT_HISTORY));
}
private String getJsDialogTitle(String url) {
String title = url;
if (URLUtil.isDataUrl(url)) {
// For data: urls, we just display 'JavaScript' similar to Safari.
title = mContext.getString(R.string.js_dialog_title_default);
} else {
try {
URL aUrl = new URL(url);
// For example: "The page at 'http://www.mit.edu' says:"
title = mContext.getString(R.string.js_dialog_title,
aUrl.getProtocol() + "://" + aUrl.getHost());
} catch (MalformedURLException ex) {
// do nothing. just use the url as the title
}
}
return title;
}
//--------------------------------------------------------------------------
// WebViewClient functions.
// NOTE: shouldOverrideKeyEvent is never called from the WebCore thread so

View File

@@ -38,13 +38,20 @@ import android.text.method.MovementMethod;
import android.text.method.PasswordTransformationMethod;
import android.text.method.TextKeyListener;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;
import android.view.ViewConfiguration;
import android.widget.AbsoluteLayout.LayoutParams;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
import java.util.ArrayList;
/**
* TextDialog is a specialized version of EditText used by WebView
@@ -281,7 +288,7 @@ import android.widget.AutoCompleteTextView;
}
return false;
}
/**
* Determine whether this TextDialog currently represents the node
* represented by ptr.
@@ -406,6 +413,9 @@ import android.widget.AutoCompleteTextView;
* focus to the host.
*/
/* package */ void remove() {
// hide the soft keyboard when the edit text is out of focus
InputMethodManager.getInstance(mContext).hideSoftInputFromWindow(
getWindowToken(), 0);
mHandler.removeMessages(LONGPRESS);
mWebView.removeView(this);
mWebView.requestFocus();
@@ -427,6 +437,43 @@ import android.widget.AutoCompleteTextView;
mWebView.passToJavaScript(getText().toString(), event);
}
public void setAdapterCustom(AutoCompleteAdapter adapter) {
adapter.setTextView(this);
super.setAdapter(adapter);
}
/**
* This is a special version of ArrayAdapter which changes its text size
* to match the text size of its host TextView.
*/
public static class AutoCompleteAdapter extends ArrayAdapter<String> {
private TextView mTextView;
public AutoCompleteAdapter(Context context, ArrayList<String> entries) {
super(context, com.android.internal.R.layout
.search_dropdown_item_1line, entries);
}
/**
* {@inheritDoc}
*/
public View getView(int position, View convertView, ViewGroup parent) {
TextView tv =
(TextView) super.getView(position, convertView, parent);
if (tv != null && mTextView != null) {
tv.setTextSize(mTextView.getTextSize());
}
return tv;
}
/**
* Set the TextView so we can match its text size.
*/
private void setTextView(TextView tv) {
mTextView = tv;
}
}
/**
* Determine whether to use the system-wide password disguising method,
* or to use none.

View File

@@ -57,6 +57,7 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.inputmethod.InputMethodManager;
import android.webkit.TextDialog.AutoCompleteAdapter;
import android.webkit.WebViewCore.EventHub;
import android.widget.AbsoluteLayout;
import android.widget.AdapterView;
@@ -2819,10 +2820,8 @@ public class WebView extends AbsoluteLayout
public void run() {
ArrayList<String> pastEntries = mDatabase.getFormData(mUrl, mName);
if (pastEntries.size() > 0) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
mContext, com.android.internal.R.layout
.search_dropdown_item_1line,
pastEntries);
AutoCompleteAdapter adapter = new
AutoCompleteAdapter(mContext, pastEntries);
((HashMap) mUpdateMessage.obj).put("adapter", adapter);
mUpdateMessage.sendToTarget();
}
@@ -4458,9 +4457,9 @@ public class WebView extends AbsoluteLayout
case UPDATE_TEXT_ENTRY_ADAPTER:
HashMap data = (HashMap) msg.obj;
if (mTextEntry.isSameTextField(msg.arg1)) {
ArrayAdapter<String> adapter =
(ArrayAdapter<String>) data.get("adapter");
mTextEntry.setAdapter(adapter);
AutoCompleteAdapter adapter =
(AutoCompleteAdapter) data.get("adapter");
mTextEntry.setAdapterCustom(adapter);
}
break;
case UPDATE_CLIPBOARD:

View File

@@ -413,7 +413,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe
// when the selection is at the bottom, we block the
// event to avoid going to the next focusable widget
Adapter adapter = mDropDownList.getAdapter();
if (curIndex == adapter.getCount() - 1) {
if (adapter != null && curIndex == adapter.getCount() - 1) {
return true;
}
}

View File

@@ -393,6 +393,12 @@ public class MediaController extends FrameLayout {
doPauseResume();
show(sDefaultTimeout);
return true;
} else if (keyCode == KeyEvent.KEYCODE_STOP) {
if (mPlayer.isPlaying()) {
mPlayer.pause();
updatePausePlay();
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ||
keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
// don't show the controls for volume adjustment

View File

@@ -447,7 +447,8 @@ public class VideoView extends SurfaceView implements MediaPlayerControl {
keyCode != KeyEvent.KEYCODE_ENDCALL &&
mMediaPlayer != null &&
mMediaController != null) {
if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK) {
if (keyCode == KeyEvent.KEYCODE_HEADSETHOOK ||
keyCode == KeyEvent.KEYCODE_PLAYPAUSE) {
if (mMediaPlayer.isPlaying()) {
pause();
mMediaController.show();
@@ -456,6 +457,10 @@ public class VideoView extends SurfaceView implements MediaPlayerControl {
mMediaController.hide();
}
return true;
} else if (keyCode == KeyEvent.KEYCODE_STOP
&& mMediaPlayer.isPlaying()) {
pause();
mMediaController.show();
} else {
toggleMediaControlsVisiblity();
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright (C) 2008 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.internal.gadget;
import android.content.ComponentName;
import android.gadget.GadgetInfo;
/** {@hide} */
interface IGadgetService {
int allocateGadgetId(String hostPackage);
void deleteGadgetId(int gadgetId);
void bindGadgetId(int gadgetId, in ComponentName provider);
GadgetInfo getGadgetInfo(int gadgetId);
}

View File

@@ -0,0 +1,3 @@
<body>
{@hide}
</body>

View File

@@ -116,7 +116,7 @@ public class HandlerCaller {
}
public Message obtainMessageI(int what, int arg1) {
return mH.obtainMessage(what, arg1);
return mH.obtainMessage(what, arg1, 0);
}
public Message obtainMessageIO(int what, int arg1, Object arg2) {

View File

@@ -143,7 +143,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie
void setCaptionMode(boolean shortcut) {
mShortcutCaptionMode = shortcut;
mShortcutCaptionMode = shortcut && (mItemData.shouldShowShortcut());
/*
* If there is no item model, don't do any of the below (for example,
@@ -155,7 +155,7 @@ public final class IconMenuItemView extends TextView implements MenuView.ItemVie
CharSequence text = mItemData.getTitleForItemView(this);
if (shortcut) {
if (mShortcutCaptionMode) {
if (mShortcutCaption == null) {
mShortcutCaption = mItemData.getShortcutLabel();

View File

@@ -171,9 +171,13 @@ public class ListMenuItemView extends LinearLayout implements MenuView.ItemView
}
public void setShortcut(boolean showShortcut, char shortcutKey) {
mShortcutView.setText(mItemData.getShortcutLabel());
final int newVisibility = (showShortcut && mItemData.shouldShowShortcut())
? VISIBLE : GONE;
if (newVisibility == VISIBLE) {
mShortcutView.setText(mItemData.getShortcutLabel());
}
final int newVisibility = showShortcut ? VISIBLE : GONE;
if (mShortcutView.getVisibility() != newVisibility) {
mShortcutView.setVisibility(newVisibility);
}

View File

@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@@ -279,7 +280,8 @@ public class MenuBuilder implements Menu {
mVisibleItems = new ArrayList<MenuItemImpl>();
mIsVisibleItemsStale = true;
mShortcutsVisible = true;
mShortcutsVisible =
(mResources.getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS);
}
public void setCallback(Callback callback) {
@@ -687,7 +689,8 @@ public class MenuBuilder implements Menu {
}
/**
* Sets whether the shortcuts should be visible on menus.
* Sets whether the shortcuts should be visible on menus. Devices without hardware
* key input will never make shortcuts visible even if this method is passed 'true'.
*
* @param shortcutsVisible Whether shortcuts should be visible (if true and a
* menu item does not have a shortcut defined, that item will
@@ -696,9 +699,11 @@ public class MenuBuilder implements Menu {
public void setShortcutsVisible(boolean shortcutsVisible) {
if (mShortcutsVisible == shortcutsVisible) return;
mShortcutsVisible = shortcutsVisible;
mShortcutsVisible =
(mResources.getConfiguration().keyboard != Configuration.KEYBOARD_NOKEYS)
&& shortcutsVisible;
refreshShortcuts(shortcutsVisible, isQwertyMode());
refreshShortcuts(mShortcutsVisible, isQwertyMode());
}
/**

View File

@@ -131,6 +131,7 @@ public class NumberPicker extends LinearLayout implements OnClickListener,
mText = (TextView) findViewById(R.id.timepicker_input);
mText.setOnFocusChangeListener(this);
mText.setFilters(new InputFilter[] { mInputFilter });
mText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
mSlideUpOutAnimation = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF,