diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-01-20 14:03:58 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-01-20 14:03:58 -0800 |
commit | 22f7dfd23490a3de2f21ff96949ba47003aac8f8 (patch) | |
tree | 41bc290bb2f1f08a0e37cfda4955742a85d42ecf /core | |
parent | 9266c558bf1d21ff647525ff99f7dadbca417309 (diff) | |
download | frameworks_base-22f7dfd23490a3de2f21ff96949ba47003aac8f8.zip frameworks_base-22f7dfd23490a3de2f21ff96949ba47003aac8f8.tar.gz frameworks_base-22f7dfd23490a3de2f21ff96949ba47003aac8f8.tar.bz2 |
auto import from //branches/cupcake/...@127101
Diffstat (limited to 'core')
100 files changed, 1677 insertions, 232 deletions
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java index 495156e..5af08f7 100644 --- a/core/java/android/app/SearchDialog.java +++ b/core/java/android/app/SearchDialog.java @@ -1129,6 +1129,15 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS } /** + * 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". */ diff --git a/core/java/android/bluetooth/BluetoothA2dp.java b/core/java/android/bluetooth/BluetoothA2dp.java index 022a87c..b0b0154 100644 --- a/core/java/android/bluetooth/BluetoothA2dp.java +++ b/core/java/android/bluetooth/BluetoothA2dp.java @@ -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 diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java index 905173e..c315271 100644 --- a/core/java/android/bluetooth/BluetoothHeadset.java +++ b/core/java/android/bluetooth/BluetoothHeadset.java @@ -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. @@ -97,14 +101,6 @@ public class BluetoothHeadset { } /** - * 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. */ public BluetoothHeadset(Context context, ServiceListener l) { @@ -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); - } - } - }; } diff --git a/core/java/android/bluetooth/IBluetoothA2dp.aidl b/core/java/android/bluetooth/IBluetoothA2dp.aidl index 7e0226d..55ff27f 100644 --- a/core/java/android/bluetooth/IBluetoothA2dp.aidl +++ b/core/java/android/bluetooth/IBluetoothA2dp.aidl @@ -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); } diff --git a/core/java/android/bluetooth/IBluetoothHeadset.aidl b/core/java/android/bluetooth/IBluetoothHeadset.aidl index 564861f..582d4e3 100644 --- a/core/java/android/bluetooth/IBluetoothHeadset.aidl +++ b/core/java/android/bluetooth/IBluetoothHeadset.aidl @@ -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); } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 6da00df..3908aa1 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -1249,6 +1249,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. * diff --git a/core/java/android/gadget/GadgetHost.java b/core/java/android/gadget/GadgetHost.java new file mode 100644 index 0000000..418f2aa --- /dev/null +++ b/core/java/android/gadget/GadgetHost.java @@ -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); + } +} + diff --git a/core/java/android/gadget/GadgetHostView.java b/core/java/android/gadget/GadgetHostView.java new file mode 100644 index 0000000..e2bef8c --- /dev/null +++ b/core/java/android/gadget/GadgetHostView.java @@ -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). + } +} + diff --git a/core/java/android/bluetooth/IBluetoothHeadsetCallback.aidl b/core/java/android/gadget/GadgetInfo.aidl index 03e884b..7231545 100644 --- a/core/java/android/bluetooth/IBluetoothHeadsetCallback.aidl +++ b/core/java/android/gadget/GadgetInfo.aidl @@ -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; diff --git a/core/java/android/gadget/GadgetInfo.java b/core/java/android/gadget/GadgetInfo.java new file mode 100644 index 0000000..1a7a9a0 --- /dev/null +++ b/core/java/android/gadget/GadgetInfo.java @@ -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 + ")"; + } +} + + diff --git a/core/java/android/gadget/GadgetManager.java b/core/java/android/gadget/GadgetManager.java new file mode 100644 index 0000000..49c706e --- /dev/null +++ b/core/java/android/gadget/GadgetManager.java @@ -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); + } + } +} + diff --git a/core/java/android/gadget/package.html b/core/java/android/gadget/package.html new file mode 100644 index 0000000..280ccfb --- /dev/null +++ b/core/java/android/gadget/package.html @@ -0,0 +1,4 @@ +<body> +@hide +</body> + diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index e2d7097..c09567c 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -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: diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 21bb38e..1a7547d 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -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); } @@ -469,6 +480,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. */ @@ -493,6 +527,27 @@ public class InputMethodService extends AbstractInputMethodService { } /** + * 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() { } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 7b64405..a18f37c 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -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. */ diff --git a/core/java/android/provider/UserDictionary.java b/core/java/android/provider/UserDictionary.java new file mode 100644 index 0000000..58e5731 --- /dev/null +++ b/core/java/android/provider/UserDictionary.java @@ -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. + } + } +} diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java index 90ef8f6..be784ff 100644 --- a/core/java/android/server/BluetoothA2dpService.java +++ b/core/java/android/server/BluetoothA2dpService.java @@ -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); - } diff --git a/core/java/android/speech/srec/Recognizer.java b/core/java/android/speech/srec/Recognizer.java index 749c923..a03a36a 100644 --- a/core/java/android/speech/srec/Recognizer.java +++ b/core/java/android/speech/srec/Recognizer.java @@ -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); // diff --git a/core/java/android/speech/srec/WaveHeader.java b/core/java/android/speech/srec/WaveHeader.java index 0aa3cc2..a99496d 100644 --- a/core/java/android/speech/srec/WaveHeader.java +++ b/core/java/android/speech/srec/WaveHeader.java @@ -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); + } } diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java index 9d7a124..9e0289a 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -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)) { diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index a676234..ba40782 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -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; diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java index cae94c9..4f8e5e4 100644 --- a/core/java/android/webkit/CallbackProxy.java +++ b/core/java/android/webkit/CallbackProxy.java @@ -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 diff --git a/core/java/android/webkit/TextDialog.java b/core/java/android/webkit/TextDialog.java index 30b519a..b7b40b1 100644 --- a/core/java/android/webkit/TextDialog.java +++ b/core/java/android/webkit/TextDialog.java @@ -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. diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index f00238d..9cfc622 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -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: diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 024b663..7d52901 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -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; } } diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java index 6c0c164..f2cec92 100644 --- a/core/java/android/widget/MediaController.java +++ b/core/java/android/widget/MediaController.java @@ -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 diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java index df40156..1227afd 100644 --- a/core/java/android/widget/VideoView.java +++ b/core/java/android/widget/VideoView.java @@ -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(); } diff --git a/core/java/com/android/internal/gadget/IGadgetService.aidl b/core/java/com/android/internal/gadget/IGadgetService.aidl new file mode 100644 index 0000000..0117d1d --- /dev/null +++ b/core/java/com/android/internal/gadget/IGadgetService.aidl @@ -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); +} diff --git a/core/java/com/android/internal/gadget/package.html b/core/java/com/android/internal/gadget/package.html new file mode 100644 index 0000000..db6f78b --- /dev/null +++ b/core/java/com/android/internal/gadget/package.html @@ -0,0 +1,3 @@ +<body> +{@hide} +</body>
\ No newline at end of file diff --git a/core/java/com/android/internal/os/HandlerCaller.java b/core/java/com/android/internal/os/HandlerCaller.java index a7081e3..1ec74a1 100644 --- a/core/java/com/android/internal/os/HandlerCaller.java +++ b/core/java/com/android/internal/os/HandlerCaller.java @@ -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) { diff --git a/core/java/com/android/internal/view/menu/IconMenuItemView.java b/core/java/com/android/internal/view/menu/IconMenuItemView.java index 3b11a64..558a4c3 100644 --- a/core/java/com/android/internal/view/menu/IconMenuItemView.java +++ b/core/java/com/android/internal/view/menu/IconMenuItemView.java @@ -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(); diff --git a/core/java/com/android/internal/view/menu/ListMenuItemView.java b/core/java/com/android/internal/view/menu/ListMenuItemView.java index e5d57ad..32513cd 100644 --- a/core/java/com/android/internal/view/menu/ListMenuItemView.java +++ b/core/java/com/android/internal/view/menu/ListMenuItemView.java @@ -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); } diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java index 2987602..cbc4e9f 100644 --- a/core/java/com/android/internal/view/menu/MenuBuilder.java +++ b/core/java/com/android/internal/view/menu/MenuBuilder.java @@ -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()); } /** diff --git a/core/java/com/android/internal/widget/NumberPicker.java b/core/java/com/android/internal/widget/NumberPicker.java index 5590f1a..20ea6a6 100644 --- a/core/java/com/android/internal/widget/NumberPicker.java +++ b/core/java/com/android/internal/widget/NumberPicker.java @@ -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, diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index e1ef459..a81f252 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -70,6 +70,10 @@ sp<Camera> get_native_camera(JNIEnv *env, jobject thiz) static void err_callback(status_t err, void *cookie) { JNIEnv *env = AndroidRuntime::getJNIEnv(); + if (env == NULL) { + LOGE("err_callback on dead VM"); + return; + } callback_cookie *c = (callback_cookie *)cookie; int error; @@ -176,6 +180,10 @@ static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz, static void preview_callback(const sp<IMemory>& mem, void *cookie) { JNIEnv *env = AndroidRuntime::getJNIEnv(); + if (env == NULL) { + LOGE("preview_callback on dead VM"); + return; + } callback_cookie *c = (callback_cookie *)cookie; int arg1 = 0, arg2 = 0; jobject obj = NULL; @@ -234,7 +242,7 @@ static bool android_hardware_Camera_previewEnabled(JNIEnv *env, jobject thiz) return c->previewEnabled(); } -static void android_hardware_Camera_setHasPreviewCallback(JNIEnv *env, jobject thiz, jboolean installed) +static void android_hardware_Camera_setHasPreviewCallback(JNIEnv *env, jobject thiz, jboolean installed, jboolean oneshot) { sp<Camera> c = get_native_camera(env, thiz); if (c == 0) @@ -245,14 +253,22 @@ static void android_hardware_Camera_setHasPreviewCallback(JNIEnv *env, jobject t // each preview frame for nothing. callback_cookie *cookie = (callback_cookie *)env->GetIntField(thiz, fields.listener_context); - c->setFrameCallback(installed ? preview_callback : NULL, - cookie, - installed ? FRAME_CALLBACK_FLAG_CAMERA: FRAME_CALLBACK_FLAG_NOOP); + int callback_flag; + if (installed) { + callback_flag = oneshot ? FRAME_CALLBACK_FLAG_BARCODE_SCANNER : FRAME_CALLBACK_FLAG_CAMERA; + } else { + callback_flag = FRAME_CALLBACK_FLAG_NOOP; + } + c->setFrameCallback(installed ? preview_callback : NULL, cookie, callback_flag); } static void autofocus_callback_impl(bool success, void *cookie) { JNIEnv *env = AndroidRuntime::getJNIEnv(); + if (env == NULL) { + LOGE("autofocus_callback on dead VM"); + return; + } callback_cookie *c = (callback_cookie *)cookie; env->CallStaticVoidMethod(c->camera_class, fields.post_event, c->camera_ref, kAutoFocusCallback, @@ -276,6 +292,10 @@ static void android_hardware_Camera_autoFocus(JNIEnv *env, jobject thiz) static void jpeg_callback(const sp<IMemory>& mem, void *cookie) { JNIEnv *env = AndroidRuntime::getJNIEnv(); + if (env == NULL) { + LOGE("jpeg`_callback on dead VM"); + return; + } callback_cookie *c = (callback_cookie *)cookie; int arg1 = 0, arg2 = 0; jobject obj = NULL; @@ -319,6 +339,10 @@ static void jpeg_callback(const sp<IMemory>& mem, void *cookie) static void shutter_callback_impl(void *cookie) { JNIEnv *env = AndroidRuntime::getJNIEnv(); + if (env == NULL) { + LOGE("shutter_callback on dead VM"); + return; + } callback_cookie *c = (callback_cookie *)cookie; env->CallStaticVoidMethod(c->camera_class, fields.post_event, c->camera_ref, kShutterCallback, 0, 0, NULL); @@ -328,6 +352,10 @@ static void raw_callback(const sp<IMemory>& mem __attribute__((unused)), void *cookie) { JNIEnv *env = AndroidRuntime::getJNIEnv(); + if (env == NULL) { + LOGE("raw_callback on dead VM"); + return; + } callback_cookie *c = (callback_cookie *)cookie; env->CallStaticVoidMethod(c->camera_class, fields.post_event, c->camera_ref, kRawCallback, 0, 0, NULL); @@ -404,7 +432,7 @@ static jint android_hardware_Camera_unlock(JNIEnv *env, jobject thiz) sp<Camera> c = get_native_camera(env, thiz); if (c == 0) return INVALID_OPERATION; - return (jint) c->lock(); + return (jint) c->unlock(); } //------------------------------------------------- @@ -429,7 +457,7 @@ static JNINativeMethod camMethods[] = { "()Z", (void *)android_hardware_Camera_previewEnabled }, { "setHasPreviewCallback", - "(Z)V", + "(ZZ)V", (void *)android_hardware_Camera_setHasPreviewCallback }, { "native_autoFocus", "()V", diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 29c1f52..ded909f 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -156,6 +156,24 @@ android:label="@string/permlab_writeCalendar" android:description="@string/permdesc_writeCalendar" /> + <!-- Allows an application to read the user dictionary. This should + really only be required by an IME, or a dictionary editor like + the Settings app. + @hide Pending API council approval --> + <permission android:name="android.permission.READ_USER_DICTIONARY" + android:permissionGroup="android.permission-group.PERSONAL_INFO" + android:protectionLevel="dangerous" + android:label="@string/permlab_readDictionary" + android:description="@string/permdesc_readDictionary" /> + + <!-- Allows an application to write to the user dictionary. + @hide Pending API council approval --> + <permission android:name="android.permission.WRITE_USER_DICTIONARY" + android:permissionGroup="android.permission-group.PERSONAL_INFO" + android:protectionLevel="normal" + android:label="@string/permlab_writeDictionary" + android:description="@string/permdesc_writeDictionary" /> + <!-- ======================================= --> <!-- Permissions for accessing location info --> <!-- ======================================= --> diff --git a/core/res/res/drawable/btn_check_off_longpress.png b/core/res/res/drawable/btn_check_off_longpress.png Binary files differdeleted file mode 100644 index c81e119..0000000 --- a/core/res/res/drawable/btn_check_off_longpress.png +++ /dev/null diff --git a/core/res/res/drawable/btn_check_on_longpress.png b/core/res/res/drawable/btn_check_on_longpress.png Binary files differdeleted file mode 100644 index 367760b..0000000 --- a/core/res/res/drawable/btn_check_on_longpress.png +++ /dev/null diff --git a/core/res/res/drawable/emo_im_angel.png b/core/res/res/drawable/emo_im_angel.png Binary files differnew file mode 100644 index 0000000..c34dfa6 --- /dev/null +++ b/core/res/res/drawable/emo_im_angel.png diff --git a/core/res/res/drawable/emo_im_cool.png b/core/res/res/drawable/emo_im_cool.png Binary files differnew file mode 100644 index 0000000..d8eeb34 --- /dev/null +++ b/core/res/res/drawable/emo_im_cool.png diff --git a/core/res/res/drawable/emo_im_crying.png b/core/res/res/drawable/emo_im_crying.png Binary files differnew file mode 100644 index 0000000..1cafdb3 --- /dev/null +++ b/core/res/res/drawable/emo_im_crying.png diff --git a/core/res/res/drawable/emo_im_embarrassed.png b/core/res/res/drawable/emo_im_embarrassed.png Binary files differnew file mode 100644 index 0000000..e4db963 --- /dev/null +++ b/core/res/res/drawable/emo_im_embarrassed.png diff --git a/core/res/res/drawable/emo_im_foot_in_mouth.png b/core/res/res/drawable/emo_im_foot_in_mouth.png Binary files differnew file mode 100644 index 0000000..09d1fba --- /dev/null +++ b/core/res/res/drawable/emo_im_foot_in_mouth.png diff --git a/core/res/res/drawable/emo_im_happy.png b/core/res/res/drawable/emo_im_happy.png Binary files differnew file mode 100644 index 0000000..b86602a --- /dev/null +++ b/core/res/res/drawable/emo_im_happy.png diff --git a/core/res/res/drawable/emo_im_kissing.png b/core/res/res/drawable/emo_im_kissing.png Binary files differnew file mode 100644 index 0000000..56378f6 --- /dev/null +++ b/core/res/res/drawable/emo_im_kissing.png diff --git a/core/res/res/drawable/emo_im_laughing.png b/core/res/res/drawable/emo_im_laughing.png Binary files differnew file mode 100644 index 0000000..980bf28 --- /dev/null +++ b/core/res/res/drawable/emo_im_laughing.png diff --git a/core/res/res/drawable/emo_im_lips_are_sealed.png b/core/res/res/drawable/emo_im_lips_are_sealed.png Binary files differnew file mode 100644 index 0000000..f2de993 --- /dev/null +++ b/core/res/res/drawable/emo_im_lips_are_sealed.png diff --git a/core/res/res/drawable/emo_im_money_mouth.png b/core/res/res/drawable/emo_im_money_mouth.png Binary files differnew file mode 100644 index 0000000..08c53fd --- /dev/null +++ b/core/res/res/drawable/emo_im_money_mouth.png diff --git a/core/res/res/drawable/emo_im_sad.png b/core/res/res/drawable/emo_im_sad.png Binary files differnew file mode 100644 index 0000000..31c08d0 --- /dev/null +++ b/core/res/res/drawable/emo_im_sad.png diff --git a/core/res/res/drawable/emo_im_surprised.png b/core/res/res/drawable/emo_im_surprised.png Binary files differnew file mode 100644 index 0000000..abe8c7a --- /dev/null +++ b/core/res/res/drawable/emo_im_surprised.png diff --git a/core/res/res/drawable/emo_im_tongue_sticking_out.png b/core/res/res/drawable/emo_im_tongue_sticking_out.png Binary files differnew file mode 100644 index 0000000..6f0f47b --- /dev/null +++ b/core/res/res/drawable/emo_im_tongue_sticking_out.png diff --git a/core/res/res/drawable/emo_im_undecided.png b/core/res/res/drawable/emo_im_undecided.png Binary files differnew file mode 100644 index 0000000..eb4f8c5 --- /dev/null +++ b/core/res/res/drawable/emo_im_undecided.png diff --git a/core/res/res/drawable/emo_im_winking.png b/core/res/res/drawable/emo_im_winking.png Binary files differnew file mode 100644 index 0000000..568562a --- /dev/null +++ b/core/res/res/drawable/emo_im_winking.png diff --git a/core/res/res/drawable/emo_im_wtf.png b/core/res/res/drawable/emo_im_wtf.png Binary files differnew file mode 100644 index 0000000..41dd47f --- /dev/null +++ b/core/res/res/drawable/emo_im_wtf.png diff --git a/core/res/res/drawable/emo_im_yelling.png b/core/res/res/drawable/emo_im_yelling.png Binary files differnew file mode 100644 index 0000000..c3c8612 --- /dev/null +++ b/core/res/res/drawable/emo_im_yelling.png diff --git a/core/res/res/drawable/ic_menu_account_list.png b/core/res/res/drawable/ic_menu_account_list.png Binary files differnew file mode 100644 index 0000000..f0945b2 --- /dev/null +++ b/core/res/res/drawable/ic_menu_account_list.png diff --git a/core/res/res/drawable/ic_menu_allfriends.png b/core/res/res/drawable/ic_menu_allfriends.png Binary files differnew file mode 100755 index 0000000..a5bd331 --- /dev/null +++ b/core/res/res/drawable/ic_menu_allfriends.png diff --git a/core/res/res/drawable/ic_menu_archive.png b/core/res/res/drawable/ic_menu_archive.png Binary files differnew file mode 100644 index 0000000..a4599e3 --- /dev/null +++ b/core/res/res/drawable/ic_menu_archive.png diff --git a/core/res/res/drawable/ic_menu_attachment.png b/core/res/res/drawable/ic_menu_attachment.png Binary files differnew file mode 100644 index 0000000..89d626f --- /dev/null +++ b/core/res/res/drawable/ic_menu_attachment.png diff --git a/core/res/res/drawable/ic_menu_back.png b/core/res/res/drawable/ic_menu_back.png Binary files differnew file mode 100644 index 0000000..5ce50eb --- /dev/null +++ b/core/res/res/drawable/ic_menu_back.png diff --git a/core/res/res/drawable/ic_menu_block.png b/core/res/res/drawable/ic_menu_block.png Binary files differnew file mode 100644 index 0000000..422eeb1 --- /dev/null +++ b/core/res/res/drawable/ic_menu_block.png diff --git a/core/res/res/drawable/ic_menu_blocked_user.png b/core/res/res/drawable/ic_menu_blocked_user.png Binary files differnew file mode 100644 index 0000000..5a5619b --- /dev/null +++ b/core/res/res/drawable/ic_menu_blocked_user.png diff --git a/core/res/res/drawable/ic_menu_cc.png b/core/res/res/drawable/ic_menu_cc.png Binary files differnew file mode 100644 index 0000000..4876021 --- /dev/null +++ b/core/res/res/drawable/ic_menu_cc.png diff --git a/core/res/res/drawable/ic_menu_chat_dashboard.png b/core/res/res/drawable/ic_menu_chat_dashboard.png Binary files differnew file mode 100644 index 0000000..37fd3cb --- /dev/null +++ b/core/res/res/drawable/ic_menu_chat_dashboard.png diff --git a/core/res/res/drawable/ic_menu_clear_playlist.png b/core/res/res/drawable/ic_menu_clear_playlist.png Binary files differnew file mode 100644 index 0000000..750db62 --- /dev/null +++ b/core/res/res/drawable/ic_menu_clear_playlist.png diff --git a/core/res/res/drawable/ic_menu_compose.png b/core/res/res/drawable/ic_menu_compose.png Binary files differnew file mode 100644 index 0000000..1b4733e --- /dev/null +++ b/core/res/res/drawable/ic_menu_compose.png diff --git a/core/res/res/drawable/ic_menu_emoticons.png b/core/res/res/drawable/ic_menu_emoticons.png Binary files differnew file mode 100644 index 0000000..e8c4e47 --- /dev/null +++ b/core/res/res/drawable/ic_menu_emoticons.png diff --git a/core/res/res/drawable/ic_menu_end_conversation.png b/core/res/res/drawable/ic_menu_end_conversation.png Binary files differnew file mode 100644 index 0000000..0ea0fcb --- /dev/null +++ b/core/res/res/drawable/ic_menu_end_conversation.png diff --git a/core/res/res/drawable/ic_menu_forward.png b/core/res/res/drawable/ic_menu_forward.png Binary files differnew file mode 100644 index 0000000..0936fac --- /dev/null +++ b/core/res/res/drawable/ic_menu_forward.png diff --git a/core/res/res/drawable/ic_menu_friendslist.png b/core/res/res/drawable/ic_menu_friendslist.png Binary files differnew file mode 100644 index 0000000..8ec6b1a --- /dev/null +++ b/core/res/res/drawable/ic_menu_friendslist.png diff --git a/core/res/res/drawable/ic_menu_goto.png b/core/res/res/drawable/ic_menu_goto.png Binary files differnew file mode 100644 index 0000000..40183eb --- /dev/null +++ b/core/res/res/drawable/ic_menu_goto.png diff --git a/core/res/res/drawable/ic_menu_home.png b/core/res/res/drawable/ic_menu_home.png Binary files differnew file mode 100644 index 0000000..34943f6 --- /dev/null +++ b/core/res/res/drawable/ic_menu_home.png diff --git a/core/res/res/drawable/ic_menu_invite.png b/core/res/res/drawable/ic_menu_invite.png Binary files differnew file mode 100644 index 0000000..7577e6d --- /dev/null +++ b/core/res/res/drawable/ic_menu_invite.png diff --git a/core/res/res/drawable/ic_menu_mark.png b/core/res/res/drawable/ic_menu_mark.png Binary files differnew file mode 100644 index 0000000..5e95da7 --- /dev/null +++ b/core/res/res/drawable/ic_menu_mark.png diff --git a/core/res/res/drawable/ic_menu_play_clip.png b/core/res/res/drawable/ic_menu_play_clip.png Binary files differnew file mode 100644 index 0000000..4669947 --- /dev/null +++ b/core/res/res/drawable/ic_menu_play_clip.png diff --git a/core/res/res/drawable/ic_menu_star.png b/core/res/res/drawable/ic_menu_star.png Binary files differnew file mode 100755 index 0000000..527d74a --- /dev/null +++ b/core/res/res/drawable/ic_menu_star.png diff --git a/core/res/res/drawable/ic_menu_start_conversation.png b/core/res/res/drawable/ic_menu_start_conversation.png Binary files differnew file mode 100644 index 0000000..aadcc2f --- /dev/null +++ b/core/res/res/drawable/ic_menu_start_conversation.png diff --git a/core/res/res/drawable/ic_menu_stop.png b/core/res/res/drawable/ic_menu_stop.png Binary files differnew file mode 100644 index 0000000..4fc825c --- /dev/null +++ b/core/res/res/drawable/ic_menu_stop.png diff --git a/core/res/res/drawable/ic_power.png b/core/res/res/drawable/ic_power.png Binary files differdeleted file mode 100755 index cfdf422..0000000 --- a/core/res/res/drawable/ic_power.png +++ /dev/null diff --git a/core/res/res/layout/js_prompt.xml b/core/res/res/layout/js_prompt.xml new file mode 100644 index 0000000..9ab9d09 --- /dev/null +++ b/core/res/res/layout/js_prompt.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:gravity="center_horizontal" + > + + <TextView android:id="@+id/message" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + /> + + <EditText android:id="@+id/value" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:textStyle="bold" + android:selectAllOnFocus="true" + android:scrollHorizontally="true" + android:layout_marginTop="6dip" + /> + +</LinearLayout> diff --git a/core/res/res/layout/zoom_controls.xml b/core/res/res/layout/zoom_controls.xml index ec37417..729af1b 100644 --- a/core/res/res/layout/zoom_controls.xml +++ b/core/res/res/layout/zoom_controls.xml @@ -17,13 +17,7 @@ ** limitations under the License. */ --> -<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:background="@android:drawable/zoom_plate" - android:gravity="bottom" - android:paddingLeft="15dip" - android:paddingRight="15dip"> +<merge xmlns:android="http://schemas.android.com/apk/res/android"> <ZoomButton android:id="@+id/zoomIn" android:background="@android:drawable/btn_plus" android:layout_width="wrap_content" @@ -34,4 +28,4 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" /> - </LinearLayout> +</merge> diff --git a/core/res/res/layout/zoom_magnify.xml b/core/res/res/layout/zoom_magnify.xml index b424837..08a5f7b 100644 --- a/core/res/res/layout/zoom_magnify.xml +++ b/core/res/res/layout/zoom_magnify.xml @@ -17,14 +17,13 @@ ** limitations under the License. */ --> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:layout_width="fill_parent" - android:layout_height="wrap_content"> +<merge xmlns:android="http://schemas.android.com/apk/res/android"> <ZoomControls android:id="@+id/zoomControls" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:layout_width="wrap_content" android:layout_height="wrap_content" + style="@style/ZoomControls" /> <ImageView android:id="@+id/zoomMagnify" android:focusable="true" @@ -35,4 +34,4 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" /> - </RelativeLayout> +</merge> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 5859b9b..61a2c29 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -310,6 +310,14 @@ <string name="permdesc_subscribedFeedsRead">"Umožňuje aplikaci získat podrobnosti o aktuálně synchronizovaných zdrojích."</string> <string name="permlab_subscribedFeedsWrite">"zápis odebíraných zdrojů"</string> <string name="permdesc_subscribedFeedsWrite">"Umožňuje aplikaci upravit vaše aktuálně synchronizované zdroje. To může škodlivým aplikacím umožnit změnu vašich synchronizovaných zdrojů."</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"Domů"</item> <item>"Mobil"</item> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"Test FACTORY_TEST lze provést pouze u balíčků nainstalovaných ve složce /system/app."</string> <string name="factorytest_no_action">"Nebyl nalezen žádný balíček umožňující test FACTORY_TEST."</string> <string name="factorytest_reboot">"Restartovat"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"Potvrdit"</string> <string name="save_password_message">"Chcete, aby si prohlížeč zapamatoval toto heslo?"</string> <string name="save_password_notnow">"Nyní ne"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 0b2c7a7..44671e6 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -310,36 +310,44 @@ <string name="permdesc_subscribedFeedsRead">"Ermöglicht einer Anwendung, Details zu den zurzeit synchronisierten Feeds abzurufen."</string> <string name="permlab_subscribedFeedsWrite">"Abonnierte Feeds schreiben"</string> <string name="permdesc_subscribedFeedsWrite">"Ermöglicht einer Anwendung, Änderungen an den kürzlich synchronisierten Feeds vorzunehmen. Schädliche Anwendungen könnten so Ihre synchronisierten Feeds ändern."</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"Privat"</item> <item>"Mobil"</item> - <item>"Beruflich"</item> - <item>"Beruflich (Fax)"</item> - <item>"Faxnummer (privat)"</item> + <item>"Arbeit"</item> + <item>"Fax (Arbeit)"</item> + <item>"Fax (privat)"</item> <item>"Pager"</item> <item>"Andere"</item> <item>"Benutzerdefiniert"</item> </string-array> <string-array name="emailAddressTypes"> <item>"Privat"</item> - <item>"Beruflich"</item> + <item>"Arbeit"</item> <item>"Andere"</item> <item>"Benutzerdefiniert"</item> </string-array> <string-array name="postalAddressTypes"> <item>"Privat"</item> - <item>"Beruflich"</item> + <item>"Arbeit"</item> <item>"Andere"</item> <item>"Benutzerdefiniert"</item> </string-array> <string-array name="imAddressTypes"> <item>"Privat"</item> - <item>"Beruflich"</item> + <item>"Arbeit"</item> <item>"Andere"</item> <item>"Benutzerdefiniert"</item> </string-array> <string-array name="organizationTypes"> - <item>"Beruflich"</item> + <item>"Arbeit"</item> <item>"Andere"</item> <item>"Benutzerdefiniert"</item> </string-array> @@ -366,7 +374,7 @@ <string name="lockscreen_pattern_correct">"Korrekt!"</string> <string name="lockscreen_pattern_wrong">"Tut uns leid. Versuchen Sie es noch einmal."</string> <string name="lockscreen_plugged_in">"Wird aufgeladen (<xliff:g id="NUMBER">%d%%</xliff:g>)"</string> - <string name="lockscreen_low_battery">"Stecken Sie Ihr Ladegerät ein."</string> + <string name="lockscreen_low_battery">"Bitte Ladegerät anschließen"</string> <string name="lockscreen_missing_sim_message_short">"Keine SIM-Karte."</string> <string name="lockscreen_missing_sim_message">"Keine SIM-Karte im Telefon."</string> <string name="lockscreen_missing_sim_instructions">"Bitte legen Sie eine SIM-Karte ein."</string> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"Die Aktion FACTORY_TEST wird nur für unter \"/system/app\" gespeicherte Pakete unterstützt."</string> <string name="factorytest_no_action">"Es wurden kein Paket mit der Aktion FACTORY_TEST gefunden."</string> <string name="factorytest_reboot">"Neu booten"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"Bestätigen"</string> <string name="save_password_message">"Möchten Sie, dass der Browser dieses Passwort speichert?"</string> <string name="save_password_notnow">"Nicht jetzt"</string> @@ -505,7 +519,7 @@ <!-- no translation found for am (4885350190794996052) --> <skip /> <string name="pm">".."</string> - <string name="numeric_date">"<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string> + <string name="numeric_date">"<xliff:g id="DAY">%d</xliff:g>/<xliff:g id="MONTH">%m</xliff:g>/<xliff:g id="YEAR">%Y</xliff:g>"</string> <string name="wday1_date1_time1_wday2_date2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string> <string name="wday1_date1_wday2_date2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DATE1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%4$s</xliff:g>, <xliff:g id="DATE2">%5$s</xliff:g>"</string> <string name="date1_time1_date2_time2">"<xliff:g id="DATE1">%2$s</xliff:g>, <xliff:g id="TIME1">%3$s</xliff:g> – <xliff:g id="DATE2">%5$s</xliff:g>, <xliff:g id="TIME2">%6$s</xliff:g>"</string> @@ -533,36 +547,36 @@ <skip /> <!-- no translation found for month (7026169712234774086) --> <skip /> - <string name="month_day_year">"<xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string> + <string name="month_day_year">"<xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string> <!-- no translation found for month_year (9219019380312413367) --> <skip /> <string name="time_of_day">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g>"</string> - <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string> - <string name="same_year_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>"</string> - <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>"</string> - <string name="same_year_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string> - <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR">%9$s</xliff:g>"</string> - <string name="same_year_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="numeric_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>"</string> - <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>"</string> - <string name="numeric_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string> - <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string> - <string name="numeric_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_month_md1_md2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>"</string> - <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>"</string> - <string name="same_month_mdy1_mdy2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>"</string> - <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>"</string> - <string name="same_month_md1_time1_md2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="DAY1_0">%3$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="DAY2_1">%8$s</xliff:g>, <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> - <string name="abbrev_month_day_year">"<xliff:g id="MONTH">%b</xliff:g> <xliff:g id="DAY">%-d</xliff:g>, <xliff:g id="YEAR">%Y</xliff:g>"</string> + <string name="date_and_time">"<xliff:g id="HOUR">%H</xliff:g>:<xliff:g id="MINUTE">%M</xliff:g>:<xliff:g id="SECOND">%S</xliff:g> <xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%B</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string> + <string name="same_year_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string> + <string name="same_year_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string> + <string name="same_year_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string> + <string name="same_year_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR">%9$s</xliff:g>"</string> + <string name="same_year_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_year_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_year_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_year_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="numeric_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string> + <string name="numeric_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>"</string> + <string name="numeric_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string> + <string name="numeric_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>"</string> + <string name="numeric_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="numeric_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="numeric_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="numeric_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>/<xliff:g id="MONTH1">%2$s</xliff:g>/<xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>/<xliff:g id="MONTH2">%7$s</xliff:g>/<xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_month_md1_md2">"<xliff:g id="DAY1">%3$s</xliff:g>. – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>"</string> + <string name="same_month_wday1_md1_wday2_md2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>"</string> + <string name="same_month_mdy1_mdy2">"<xliff:g id="DAY1">%3$s</xliff:g>. – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string> + <string name="same_month_wday1_mdy1_wday2_mdy2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>"</string> + <string name="same_month_md1_time1_md2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_month_wday1_md1_time1_wday2_md2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_month_mdy1_time1_mdy2_time2">"<xliff:g id="DAY1">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="DAY2">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="same_month_wday1_mdy1_time1_wday2_mdy2_time2">"<xliff:g id="WEEKDAY1">%1$s</xliff:g>, <xliff:g id="DAY1_0">%3$s</xliff:g>. <xliff:g id="MONTH1">%2$s</xliff:g> <xliff:g id="YEAR1">%4$s</xliff:g>, <xliff:g id="TIME1">%5$s</xliff:g> – <xliff:g id="WEEKDAY2">%6$s</xliff:g>, <xliff:g id="DAY2_1">%8$s</xliff:g>. <xliff:g id="MONTH2">%7$s</xliff:g> <xliff:g id="YEAR2">%9$s</xliff:g>, <xliff:g id="TIME2">%10$s</xliff:g>"</string> + <string name="abbrev_month_day_year">"<xliff:g id="DAY">%-d</xliff:g>. <xliff:g id="MONTH">%b</xliff:g> <xliff:g id="YEAR">%Y</xliff:g>"</string> <!-- no translation found for abbrev_month_year (3856424847226891943) --> <skip /> <!-- no translation found for abbrev_month_day (5028815883653985933) --> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 6727d5e..07a92fa 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -310,6 +310,14 @@ <string name="permdesc_subscribedFeedsRead">"Permite que una aplicación obtenga detalles sobre los feeds sincronizados en este momento."</string> <string name="permlab_subscribedFeedsWrite">"escribir feeds a los que está suscrito el usuario"</string> <string name="permdesc_subscribedFeedsWrite">"Permite que una aplicación modifique los feeds sincronizados actualmente. Este permiso podría provocar que una aplicación malintencionada cambie los feeds sincronizados."</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"Casa"</item> <item>"Móvil"</item> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"La acción FACTORY_TEST sólo es compatible con los paquetes instalados en /system/app."</string> <string name="factorytest_no_action">"No se ha encontrado ningún paquete que proporcione la acción FACTORY_TEST."</string> <string name="factorytest_reboot">"Reiniciar"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"Confirmar"</string> <string name="save_password_message">"¿Deseas que el navegador recuerde esta contraseña?"</string> <string name="save_password_notnow">"Ahora no"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 600bc2c..0f58ba1 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -310,6 +310,14 @@ <string name="permdesc_subscribedFeedsRead">"Permet à une application d\'obtenir des informations sur les flux récemment synchronisés."</string> <string name="permlab_subscribedFeedsWrite">"Écrire les flux auxquels vous êtes abonné"</string> <string name="permdesc_subscribedFeedsWrite">"Permet à une application de modifier vos flux synchronisés actuels. Cette fonctionnalité peut permettre à des applications malveillantes de modifier vos flux synchronisés."</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"Accueil"</item> <item>"Mobile"</item> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"L\'action FACTORY_TEST est uniquement prise en charge pour les paquets de données installés dans in/system/app."</string> <string name="factorytest_no_action">"Impossible de trouver un paquet proposant l\'action FACTORY_TEST."</string> <string name="factorytest_reboot">"Redémarrer"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"Confirmer"</string> <string name="save_password_message">"Voulez-vous que le navigateur se souvienne de ce mot de passe ?"</string> <string name="save_password_notnow">"Pas maintenant"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index b41d449..8b96f89 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -310,6 +310,14 @@ <string name="permdesc_subscribedFeedsRead">"Consente a un\'applicazione di ottenere dettagli sui feed attualmente sincronizzati."</string> <string name="permlab_subscribedFeedsWrite">"scrivere feed sottoscritti"</string> <string name="permdesc_subscribedFeedsWrite">"Consente la modifica da parte di un\'applicazione dei feed attualmente sincronizzati. Le applicazioni dannose potrebbero essere in grado di modificare i feed sincronizzati."</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"Casa"</item> <item>"Cellulare"</item> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"L\'azione FACTORY_TEST è supportata soltanto per i pacchetti installati in /system/app."</string> <string name="factorytest_no_action">"Nessun pacchetto trovato che fornisca l\'azione FACTORY_TEST."</string> <string name="factorytest_reboot">"Riavvia"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"Conferma"</string> <string name="save_password_message">"Memorizzare la password nel browser?"</string> <string name="save_password_notnow">"Non ora"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 93b66f3..0735837 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -310,6 +310,14 @@ <string name="permdesc_subscribedFeedsRead">"現在同期しているフィードの詳細の取得をアプリケーションに許可します。"</string> <string name="permlab_subscribedFeedsWrite">"登録したフィードの書き込み"</string> <string name="permdesc_subscribedFeedsWrite">"現在同期しているフィードの変更をアプリケーションに許可します。悪意のあるアプリケーションが同期フィードを変更する恐れがあります。"</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"自宅"</item> <item>"携帯"</item> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"FACTORY_TEST操作は、/system/appにインストールされたパッケージのみが対象です。"</string> <string name="factorytest_no_action">"FACTORY_TEST操作を行うパッケージは見つかりませんでした。"</string> <string name="factorytest_reboot">"再起動"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"確認"</string> <string name="save_password_message">"このパスワードをブラウザで保存しますか?"</string> <string name="save_password_notnow">"今は保存しない"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 54a7321..9426f35 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -310,6 +310,14 @@ <string name="permdesc_subscribedFeedsRead">"Hiermee kan een toepassing details over de huidige gesynchroniseerde feeds achterhalen."</string> <string name="permlab_subscribedFeedsWrite">"geabonneerde feeds schrijven"</string> <string name="permdesc_subscribedFeedsWrite">"Hiermee kan een toepassing uw huidige gesynchroniseerde feeds wijzigen. Een schadelijke toepassing kan op deze manier uw gesynchroniseerde feeds wijzigen."</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"Thuis"</item> <item>"Mobiel"</item> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"De actie FACTORY_TEST wordt alleen ondersteund voor pakketten die zijn geïnstalleerd in /system/app."</string> <string name="factorytest_no_action">"Er is geen pakket gevonden dat de actie FACTORY_TEST levert."</string> <string name="factorytest_reboot">"Opnieuw opstarten"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"Bevestigen"</string> <string name="save_password_message">"Wilt u dat de browser dit wachtwoord onthoudt?"</string> <string name="save_password_notnow">"Niet nu"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index c3cf8a1..d76922f 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -310,6 +310,14 @@ <string name="permdesc_subscribedFeedsRead">"Pozwala aplikacjom na pobieranie informacji szczegółowych na temat obecnie zsynchronizowanych źródeł."</string> <string name="permlab_subscribedFeedsWrite">"zapisywanie subskrybowanych źródeł"</string> <string name="permdesc_subscribedFeedsWrite">"Umożliwia aplikacji zmianę obecnie zsynchronizowanych źródeł. Może to pozwolić szkodliwej aplikacji na zmianę zsynchronizowanych źródeł."</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"Strona główna"</item> <item>"Komórka"</item> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"Czynność FACTORY_TEST jest obsługiwana tylko dla pakietów zainstalowanych w katalogu /system/app."</string> <string name="factorytest_no_action">"Nie znaleziono żadnego pakietu, który zapewnia działanie FACTORY_TEST."</string> <string name="factorytest_reboot">"Uruchom ponownie"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"Potwierdź"</string> <string name="save_password_message">"Czy chcesz, aby zapamiętać to hasło w przeglądarce?"</string> <string name="save_password_notnow">"Nie teraz"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 8d362bd..a00973f 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -310,6 +310,14 @@ <string name="permdesc_subscribedFeedsRead">"Позволяет приложению получать сведения о синхронизированных фидах."</string> <string name="permlab_subscribedFeedsWrite">"записывать фиды с подпиской"</string> <string name="permdesc_subscribedFeedsWrite">"Разрешает приложению изменять ваши синхронизированные фиды. Это может позволить вредоносному ПО изменять ваши синхронизированные фиды."</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"Домашний"</item> <item>"Мобильный"</item> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"Действие FACTORY_TEST поддерживается только для пакетов, установленных в папке /system/app."</string> <string name="factorytest_no_action">"Пакет, предоставляющий действие FACTORY_TEST, не найден."</string> <string name="factorytest_reboot">"Перезагрузить"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"Подтверждение"</string> <string name="save_password_message">"Сохранить этот пароль в браузере?"</string> <string name="save_password_notnow">"Не сейчас"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 27b8fea..87bd4e4 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -310,6 +310,14 @@ <string name="permdesc_subscribedFeedsRead">"允许应用程序获取有关当前同步的供稿的详情。"</string> <string name="permlab_subscribedFeedsWrite">"写入订阅的供稿"</string> <string name="permdesc_subscribedFeedsWrite">"允许应用程序修改您当前同步的供稿。这样恶意程序可以更改您同步的供稿。"</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"家庭"</item> <item>"手机"</item> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"只有在 /system/app 中安装的包支持 FACTORY_TEST 操作。"</string> <string name="factorytest_no_action">"未发现支持 FACTORY_TEST 操作的包。"</string> <string name="factorytest_reboot">"重新引导"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"确认"</string> <string name="save_password_message">"是否希望浏览器记住此密码?"</string> <string name="save_password_notnow">"暂不保存"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index b95ca98..fbe8c55 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -310,6 +310,14 @@ <string name="permdesc_subscribedFeedsRead">"允許應用程式取得目前已同步處理的資訊提供。"</string> <string name="permlab_subscribedFeedsWrite">"寫入訂閱資訊提供"</string> <string name="permdesc_subscribedFeedsWrite">"允許應用程式修改已同步處理的資訊提供。惡意程式可使用此功能變更已同步處理的資訊提供。"</string> + <!-- no translation found for permlab_readDictionary (432535716804748781) --> + <skip /> + <!-- no translation found for permdesc_readDictionary (1082972603576360690) --> + <skip /> + <!-- no translation found for permlab_writeDictionary (6703109511836343341) --> + <skip /> + <!-- no translation found for permdesc_writeDictionary (2241256206524082880) --> + <skip /> <string-array name="phoneTypes"> <item>"首頁"</item> <item>"行動"</item> @@ -406,6 +414,12 @@ <string name="factorytest_not_system">"FACTORY_TEST 動作只支援安裝在 /system/app 裡的程式。"</string> <string name="factorytest_no_action">"找不到提供 FACTORY_TEST 的程式。"</string> <string name="factorytest_reboot">"重新開機"</string> + <!-- no translation found for js_dialog_title (8143918455087008109) --> + <skip /> + <!-- no translation found for js_dialog_title_default (6961903213729667573) --> + <skip /> + <!-- no translation found for js_dialog_before_unload (1901675448179653089) --> + <skip /> <string name="save_password_label">"確認"</string> <string name="save_password_message">"是否記憶此密碼?"</string> <string name="save_password_notnow">"現在不要"</string> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 1704179..2562a8a 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -2468,7 +2468,7 @@ <!-- ***************************************************************** --> <eat-comment /> - <!-- Searchable activities & applications must provide search configuration information + <!-- Searchable activities and applications must provide search configuration information in an XML file, typically called searchable.xml. This file is referenced in your manifest. For a more in-depth discussion of search configuration, please refer to {@link android.app.SearchManager}. --> @@ -2601,9 +2601,7 @@ <!-- The set of attributes for a MapView. --> <declare-styleable name="MapView"> - <!-- An API Key required to use MapView. Currently, this can be an arbitrary string. - In order to run on actual devices, though, your app will need an authentic key, but - the process for issuing keys is not ready at this time. --> + <!-- Value is a string that specifies the Maps API Key to use. --> <attr name="apiKey" format="string" /> </declare-styleable> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index cb364e6..f25d829 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -748,7 +748,7 @@ <public type="drawable" name="btn_plus" id="0x01080008" /> <public type="drawable" name="btn_radio" id="0x01080009" /> <public type="drawable" name="btn_star" id="0x0108000a" /> - <public type="drawable" name="btn_star_big_off" id="0x0108000b" /> + <public type="drawable" name="btn_star_big_off" id="0x0108000b" /> <public type="drawable" name="btn_star_big_on" id="0x0108000c" /> <public type="drawable" name="button_onoff_indicator_on" id="0x0108000d" /> <public type="drawable" name="button_onoff_indicator_off" id="0x0108000e" /> @@ -1034,10 +1034,22 @@ <public type="style" name="Theme.NoDisplay" id="0x01030055" /> <public type="style" name="Animation.InputMethod" id="0x01030056" /> <public type="style" name="Widget.KeyboardView" id="0x01030057" /> - - <public type="drawable" name="ic_btn_search" id="0x0108009e" /> - <public type="drawable" name="ic_dialog_menu_generic" id="0x010800a0" /> - <public type="drawable" name="ic_menu_login" id="0x010800a1" /> - <public type="drawable" name="ic_menu_refresh" id="0x010800a2" /> - <public type="drawable" name="ic_menu_notifications" id="0x010800a3" /> + + <public type="drawable" name="emo_im_angel" id="0x010800a4" /> + <public type="drawable" name="emo_im_cool" id="0x010800a5" /> + <public type="drawable" name="emo_im_crying" id="0x010800a6" /> + <public type="drawable" name="emo_im_embarrassed" id="0x010800a7" /> + <public type="drawable" name="emo_im_foot_in_mouth" id="0x010800a8" /> + <public type="drawable" name="emo_im_happy" id="0x010800a9" /> + <public type="drawable" name="emo_im_kissing" id="0x010800aa" /> + <public type="drawable" name="emo_im_laughing" id="0x010800ab" /> + <public type="drawable" name="emo_im_lips_are_sealed" id="0x010800ac" /> + <public type="drawable" name="emo_im_money_mouth" id="0x010800ad" /> + <public type="drawable" name="emo_im_sad" id="0x010800ae" /> + <public type="drawable" name="emo_im_surprised" id="0x010800af" /> + <public type="drawable" name="emo_im_tongue_sticking_out" id="0x010800b0" /> + <public type="drawable" name="emo_im_undecided" id="0x010800b1" /> + <public type="drawable" name="emo_im_winking" id="0x010800b2" /> + <public type="drawable" name="emo_im_wtf" id="0x010800b3" /> + <public type="drawable" name="emo_im_yelling" id="0x010800b4" /> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index f9e2e0f..978a024 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -979,6 +979,18 @@ your currently synced feeds. This could allow a malicious application to change your synced feeds.</string> + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permlab_readDictionary">read user defined dictionary</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_readDictionary">Allows an application to read any private + words, names and phrases that the user may have stored in the user dictionary.</string> + + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permlab_writeDictionary">write to user defined dictionary</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_writeDictionary">Allows an application to write new words into the + user dictionary.</string> + <!-- The order of these is important, don't reorder without changing Contacts.java --> <skip /> <!-- Phone number types from android.provider.Contacts. This could be used when adding a new phone number for a contact, for example. --> <string-array name="phoneTypes"> @@ -1216,6 +1228,14 @@ <string name="web_user_agent"><xliff:g id="x">Mozilla/5.0 (Linux; U; Android %s) AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20.1</xliff:g></string> + <!-- Title for a JavaScript dialog. "The page at <url of current page> says:" --> + <string name="js_dialog_title">The page at \'<xliff:g id="title">%s</xliff:g>\' says:</string> + <!-- Default title for a javascript dialog --> + <string name="js_dialog_title_default">JavaScript</string> + <!-- Message in a javascript dialog asking if the user wishes to leave the + current page --> + <string name="js_dialog_before_unload">Navigate away from this page?\n\n<xliff:g id="message">%s</xliff:g>\n\nSelect OK to continue, or Cancel to stay on the current page.</string> + <!-- Title of the WebView save password dialog. If the user enters a password in a form on a website, a dialog will come up asking if they want to save the password. --> <string name="save_password_label">Confirm</string> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index bc300c3..73e7dd0 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -627,4 +627,11 @@ <item name="android:shadowColor">#BB000000</item> <item name="android:shadowRadius">2.75</item> </style> + + <style name="ZoomControls"> + <item name="android:background">@android:drawable/zoom_plate</item> + <item name="android:gravity">bottom</item> + <item name="android:paddingLeft">15dip</item> + <item name="android:paddingRight">15dip</item> + </style> </resources> diff --git a/core/res/waitingroom/screen_background_blue-land.png b/core/res/waitingroom/screen_background_blue-land.png Binary files differdeleted file mode 100644 index 50e46b1..0000000 --- a/core/res/waitingroom/screen_background_blue-land.png +++ /dev/null diff --git a/core/res/waitingroom/screen_background_green-land.png b/core/res/waitingroom/screen_background_green-land.png Binary files differdeleted file mode 100644 index f46afa1..0000000 --- a/core/res/waitingroom/screen_background_green-land.png +++ /dev/null diff --git a/core/res/waitingroom/screen_background_white-land.png b/core/res/waitingroom/screen_background_white-land.png Binary files differdeleted file mode 100644 index a179c38..0000000 --- a/core/res/waitingroom/screen_background_white-land.png +++ /dev/null |