auto import from //branches/cupcake/...@127101
This commit is contained in:
@@ -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".
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
72
core/java/android/gadget/GadgetHost.java
Normal file
72
core/java/android/gadget/GadgetHost.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
102
core/java/android/gadget/GadgetHostView.java
Normal file
102
core/java/android/gadget/GadgetHostView.java
Normal 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).
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
126
core/java/android/gadget/GadgetInfo.java
Normal file
126
core/java/android/gadget/GadgetInfo.java
Normal 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 + ")";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
170
core/java/android/gadget/GadgetManager.java
Normal file
170
core/java/android/gadget/GadgetManager.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
4
core/java/android/gadget/package.html
Normal file
4
core/java/android/gadget/package.html
Normal file
@@ -0,0 +1,4 @@
|
||||
<body>
|
||||
@hide
|
||||
</body>
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
127
core/java/android/provider/UserDictionary.java
Normal file
127
core/java/android/provider/UserDictionary.java
Normal 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.
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
//
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
28
core/java/com/android/internal/gadget/IGadgetService.aidl
Normal file
28
core/java/com/android/internal/gadget/IGadgetService.aidl
Normal 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);
|
||||
}
|
||||
3
core/java/com/android/internal/gadget/package.html
Normal file
3
core/java/com/android/internal/gadget/package.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<body>
|
||||
{@hide}
|
||||
</body>
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user