diff options
38 files changed, 5922 insertions, 965 deletions
diff --git a/api/current.txt b/api/current.txt index f2b35a8..d04025c 100644 --- a/api/current.txt +++ b/api/current.txt @@ -26608,7 +26608,7 @@ package android.widget { method public abstract void onNothingSelected(android.widget.AdapterView<?>); } - public abstract class AdapterViewAnimator extends android.widget.AdapterView { + public abstract class AdapterViewAnimator extends android.widget.AdapterView implements android.widget.Advanceable { ctor public AdapterViewAnimator(android.content.Context); ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet); ctor public AdapterViewAnimator(android.content.Context, android.util.AttributeSet, int); @@ -26650,6 +26650,11 @@ package android.widget { method public void stopFlipping(); } + public abstract interface Advanceable { + method public abstract void advance(); + method public abstract void fyiWillBeAdvancedByHostKThx(); + } + public class AlphabetIndexer extends android.database.DataSetObserver implements android.widget.SectionIndexer { ctor public AlphabetIndexer(android.database.Cursor, int, java.lang.CharSequence); method protected int compare(java.lang.String, java.lang.String); diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java index 0519d3e..7e1daa4 100644 --- a/core/java/android/app/FragmentManager.java +++ b/core/java/android/app/FragmentManager.java @@ -1890,7 +1890,7 @@ final class FragmentManagerImpl extends FragmentManager { if (mActive != null) { for (int i=0; i<mAdded.size(); i++) { Fragment f = mAdded.get(i); - if (f != null && !f.mHidden) { + if (f != null && !f.mHidden && f.mUserVisibleHint) { if (f.onContextItemSelected(item)) { return true; } diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index 0640d7e..f4abda6 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -252,7 +252,7 @@ public interface IMountService extends IInterface { * an int consistent with MountServiceResultCode */ public int createSecureContainer(String id, int sizeMb, String fstype, String key, - int ownerUid) throws RemoteException { + int ownerUid, boolean external) throws RemoteException { Parcel _data = Parcel.obtain(); Parcel _reply = Parcel.obtain(); int _result; @@ -263,6 +263,7 @@ public interface IMountService extends IInterface { _data.writeString(fstype); _data.writeString(key); _data.writeInt(ownerUid); + _data.writeInt(external ? 1 : 0); mRemote.transact(Stub.TRANSACTION_createSecureContainer, _data, _reply, 0); _reply.readException(); _result = _reply.readInt(); @@ -711,6 +712,31 @@ public interface IMountService extends IInterface { } return _result; } + + /** + * Fix permissions in a container which has just been created and + * populated. Returns an int consistent with MountServiceResultCode + */ + public int fixPermissionsSecureContainer(String id, int gid, String filename) + throws RemoteException { + Parcel _data = Parcel.obtain(); + Parcel _reply = Parcel.obtain(); + int _result; + try { + _data.writeInterfaceToken(DESCRIPTOR); + _data.writeString(id); + _data.writeInt(gid); + _data.writeString(filename); + mRemote.transact(Stub.TRANSACTION_fixPermissionsSecureContainer, _data, _reply, 0); + _reply.readException(); + _result = _reply.readInt(); + } finally { + _reply.recycle(); + _data.recycle(); + } + return _result; + + } } private static final String DESCRIPTOR = "IMountService"; @@ -781,6 +807,8 @@ public interface IMountService extends IInterface { static final int TRANSACTION_verifyEncryptionPassword = IBinder.FIRST_CALL_TRANSACTION + 32; + static final int TRANSACTION_fixPermissionsSecureContainer = IBinder.FIRST_CALL_TRANSACTION + 33; + /** * Cast an IBinder object into an IMountService interface, generating a * proxy if needed. @@ -909,7 +937,10 @@ public interface IMountService extends IInterface { key = data.readString(); int ownerUid; ownerUid = data.readInt(); - int resultCode = createSecureContainer(id, sizeMb, fstype, key, ownerUid); + boolean external; + external = 0 != data.readInt(); + int resultCode = createSecureContainer(id, sizeMb, fstype, key, ownerUid, + external); reply.writeNoException(); reply.writeInt(resultCode); return true; @@ -1109,6 +1140,19 @@ public interface IMountService extends IInterface { reply.writeInt(result); return true; } + case TRANSACTION_fixPermissionsSecureContainer: { + data.enforceInterface(DESCRIPTOR); + String id; + id = data.readString(); + int gid; + gid = data.readInt(); + String filename; + filename = data.readString(); + int resultCode = fixPermissionsSecureContainer(id, gid, filename); + reply.writeNoException(); + reply.writeInt(resultCode); + return true; + } } return super.onTransact(code, data, reply, flags); } @@ -1118,8 +1162,8 @@ public interface IMountService extends IInterface { * Creates a secure container with the specified parameters. Returns an int * consistent with MountServiceResultCode */ - public int createSecureContainer(String id, int sizeMb, String fstype, String key, int ownerUid) - throws RemoteException; + public int createSecureContainer(String id, int sizeMb, String fstype, String key, + int ownerUid, boolean external) throws RemoteException; /* * Destroy a secure container, and free up all resources associated with it. @@ -1317,4 +1361,11 @@ public interface IMountService extends IInterface { public Parcelable[] getVolumeList() throws RemoteException; public String getSecureContainerFilesystemPath(String id) throws RemoteException; + + /* + * Fix permissions in a container which has just been created and populated. + * Returns an int consistent with MountServiceResultCode + */ + public int fixPermissionsSecureContainer(String id, int gid, String filename) + throws RemoteException; } diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java index 1c61c6c..5b371eb 100644 --- a/core/java/android/view/KeyCharacterMap.java +++ b/core/java/android/view/KeyCharacterMap.java @@ -153,20 +153,26 @@ public class KeyCharacterMap implements Parcelable { private static final int ACCENT_BREVE = '\u02D8'; private static final int ACCENT_CARON = '\u02C7'; private static final int ACCENT_CEDILLA = '\u00B8'; + private static final int ACCENT_CIRCUMFLEX = '\u02C6'; private static final int ACCENT_COMMA_ABOVE = '\u1FBD'; private static final int ACCENT_COMMA_ABOVE_RIGHT = '\u02BC'; private static final int ACCENT_DOT_ABOVE = '\u02D9'; + private static final int ACCENT_DOT_BELOW = '.'; // approximate private static final int ACCENT_DOUBLE_ACUTE = '\u02DD'; private static final int ACCENT_GRAVE = '\u02CB'; - private static final int ACCENT_CIRCUMFLEX = '\u02C6'; + private static final int ACCENT_HOOK_ABOVE = '\u02C0'; + private static final int ACCENT_HORN = '\''; // approximate private static final int ACCENT_MACRON = '\u00AF'; private static final int ACCENT_MACRON_BELOW = '\u02CD'; private static final int ACCENT_OGONEK = '\u02DB'; private static final int ACCENT_REVERSED_COMMA_ABOVE = '\u02BD'; private static final int ACCENT_RING_ABOVE = '\u02DA'; + private static final int ACCENT_STROKE = '-'; // approximate private static final int ACCENT_TILDE = '\u02DC'; private static final int ACCENT_TURNED_COMMA_ABOVE = '\u02BB'; private static final int ACCENT_UMLAUT = '\u00A8'; + private static final int ACCENT_VERTICAL_LINE_ABOVE = '\u02C8'; + private static final int ACCENT_VERTICAL_LINE_BELOW = '\u02CC'; /* Legacy dead key display characters used in previous versions of the API. * We still support these characters by mapping them to their non-legacy version. */ @@ -188,11 +194,11 @@ public class KeyCharacterMap implements Parcelable { addCombining('\u0306', ACCENT_BREVE); addCombining('\u0307', ACCENT_DOT_ABOVE); addCombining('\u0308', ACCENT_UMLAUT); - //addCombining('\u0309', ACCENT_HOOK_ABOVE); + addCombining('\u0309', ACCENT_HOOK_ABOVE); addCombining('\u030A', ACCENT_RING_ABOVE); addCombining('\u030B', ACCENT_DOUBLE_ACUTE); addCombining('\u030C', ACCENT_CARON); - //addCombining('\u030D', ACCENT_VERTICAL_LINE_ABOVE); + addCombining('\u030D', ACCENT_VERTICAL_LINE_ABOVE); //addCombining('\u030E', ACCENT_DOUBLE_VERTICAL_LINE_ABOVE); //addCombining('\u030F', ACCENT_DOUBLE_GRAVE); //addCombining('\u0310', ACCENT_CANDRABINDU); @@ -201,13 +207,14 @@ public class KeyCharacterMap implements Parcelable { addCombining('\u0313', ACCENT_COMMA_ABOVE); addCombining('\u0314', ACCENT_REVERSED_COMMA_ABOVE); addCombining('\u0315', ACCENT_COMMA_ABOVE_RIGHT); - //addCombining('\u031B', ACCENT_HORN); - //addCombining('\u0323', ACCENT_DOT_BELOW); + addCombining('\u031B', ACCENT_HORN); + addCombining('\u0323', ACCENT_DOT_BELOW); //addCombining('\u0326', ACCENT_COMMA_BELOW); addCombining('\u0327', ACCENT_CEDILLA); addCombining('\u0328', ACCENT_OGONEK); - //addCombining('\u0329', ACCENT_VERTICAL_LINE_BELOW); + addCombining('\u0329', ACCENT_VERTICAL_LINE_BELOW); addCombining('\u0331', ACCENT_MACRON_BELOW); + addCombining('\u0335', ACCENT_STROKE); //addCombining('\u0342', ACCENT_PERISPOMENI); //addCombining('\u0344', ACCENT_DIALYTIKA_TONOS); //addCombining('\u0345', ACCENT_YPOGEGRAMMENI); @@ -235,6 +242,33 @@ public class KeyCharacterMap implements Parcelable { */ private static final SparseIntArray sDeadKeyCache = new SparseIntArray(); private static final StringBuilder sDeadKeyBuilder = new StringBuilder(); + static { + // Non-standard decompositions. + // Stroke modifier for Finnish multilingual keyboard and others. + addDeadKey(ACCENT_STROKE, 'D', '\u0110'); + addDeadKey(ACCENT_STROKE, 'G', '\u01e4'); + addDeadKey(ACCENT_STROKE, 'H', '\u0126'); + addDeadKey(ACCENT_STROKE, 'I', '\u0197'); + addDeadKey(ACCENT_STROKE, 'L', '\u0141'); + addDeadKey(ACCENT_STROKE, 'O', '\u00d8'); + addDeadKey(ACCENT_STROKE, 'T', '\u0166'); + addDeadKey(ACCENT_STROKE, 'd', '\u0111'); + addDeadKey(ACCENT_STROKE, 'g', '\u01e5'); + addDeadKey(ACCENT_STROKE, 'h', '\u0127'); + addDeadKey(ACCENT_STROKE, 'i', '\u0268'); + addDeadKey(ACCENT_STROKE, 'l', '\u0142'); + addDeadKey(ACCENT_STROKE, 'o', '\u00f8'); + addDeadKey(ACCENT_STROKE, 't', '\u0167'); + } + + private static void addDeadKey(int accent, int c, int result) { + final int combining = sAccentToCombining.get(accent); + if (combining == 0) { + throw new IllegalStateException("Invalid dead key declaration."); + } + final int combination = (combining << 16) | c; + sDeadKeyCache.put(combination, result); + } public static final Parcelable.Creator<KeyCharacterMap> CREATOR = new Parcelable.Creator<KeyCharacterMap>() { diff --git a/core/java/android/widget/Advanceable.java b/core/java/android/widget/Advanceable.java index dc13ebb7..ad8e101 100644 --- a/core/java/android/widget/Advanceable.java +++ b/core/java/android/widget/Advanceable.java @@ -21,7 +21,6 @@ package android.widget; * progressing through its set of children. The interface exists to give AppWidgetHosts a way of * taking responsibility for automatically advancing such collections. * - * @hide */ public interface Advanceable { diff --git a/core/java/com/android/internal/app/IMediaContainerService.aidl b/core/java/com/android/internal/app/IMediaContainerService.aidl index 4322a20..727c094 100755 --- a/core/java/com/android/internal/app/IMediaContainerService.aidl +++ b/core/java/com/android/internal/app/IMediaContainerService.aidl @@ -22,14 +22,14 @@ import android.content.pm.PackageInfoLite; import android.content.res.ObbInfo; interface IMediaContainerService { - String copyResourceToContainer(in Uri packageURI, - String containerId, - String key, String resFileName); + String copyResourceToContainer(in Uri packageURI, String containerId, String key, + String resFileName, String publicResFileName, boolean isExternal, + boolean isForwardLocked); int copyResource(in Uri packageURI, in ParcelFileDescriptor outStream); PackageInfoLite getMinimalPackageInfo(in Uri fileUri, in int flags, in long threshold); - boolean checkInternalFreeStorage(in Uri fileUri, in long threshold); - boolean checkExternalFreeStorage(in Uri fileUri); + boolean checkInternalFreeStorage(in Uri fileUri, boolean isForwardLocked, in long threshold); + boolean checkExternalFreeStorage(in Uri fileUri, boolean isForwardLocked); ObbInfo getObbInfo(in String filename); long calculateDirectorySize(in String directory); /** Return file system stats: [0] is total bytes, [1] is available bytes */ diff --git a/core/java/com/android/internal/app/RingtonePickerActivity.java b/core/java/com/android/internal/app/RingtonePickerActivity.java deleted file mode 100644 index 36fc24e..0000000 --- a/core/java/com/android/internal/app/RingtonePickerActivity.java +++ /dev/null @@ -1,362 +0,0 @@ -/* - * 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 - * - * 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.app; - -import com.android.internal.app.AlertActivity; -import com.android.internal.app.AlertController; - -import android.content.DialogInterface; -import android.content.Intent; -import android.database.Cursor; -import android.media.Ringtone; -import android.media.RingtoneManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.provider.MediaStore; -import android.provider.Settings; -import android.view.View; -import android.widget.AdapterView; -import android.widget.ListView; -import android.widget.TextView; - -/** - * The {@link RingtonePickerActivity} allows the user to choose one from all of the - * available ringtones. The chosen ringtone's URI will be persisted as a string. - * - * @see RingtoneManager#ACTION_RINGTONE_PICKER - */ -public final class RingtonePickerActivity extends AlertActivity implements - AdapterView.OnItemSelectedListener, Runnable, DialogInterface.OnClickListener, - AlertController.AlertParams.OnPrepareListViewListener { - - private static final String TAG = "RingtonePickerActivity"; - - private static final int DELAY_MS_SELECTION_PLAYED = 300; - - private static final String SAVE_CLICKED_POS = "clicked_pos"; - - private RingtoneManager mRingtoneManager; - - private Cursor mCursor; - private Handler mHandler; - - /** The position in the list of the 'Silent' item. */ - private int mSilentPos = -1; - - /** The position in the list of the 'Default' item. */ - private int mDefaultRingtonePos = -1; - - /** The position in the list of the last clicked item. */ - private int mClickedPos = -1; - - /** The position in the list of the ringtone to sample. */ - private int mSampleRingtonePos = -1; - - /** Whether this list has the 'Silent' item. */ - private boolean mHasSilentItem; - - /** The Uri to place a checkmark next to. */ - private Uri mExistingUri; - - /** The number of static items in the list. */ - private int mStaticItemCount; - - /** Whether this list has the 'Default' item. */ - private boolean mHasDefaultItem; - - /** The Uri to play when the 'Default' item is clicked. */ - private Uri mUriForDefaultItem; - - /** - * A Ringtone for the default ringtone. In most cases, the RingtoneManager - * will stop the previous ringtone. However, the RingtoneManager doesn't - * manage the default ringtone for us, so we should stop this one manually. - */ - private Ringtone mDefaultRingtone; - - private DialogInterface.OnClickListener mRingtoneClickListener = - new DialogInterface.OnClickListener() { - - /* - * On item clicked - */ - public void onClick(DialogInterface dialog, int which) { - // Save the position of most recently clicked item - mClickedPos = which; - - // Play clip - playRingtone(which, 0); - } - - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mHandler = new Handler(); - - Intent intent = getIntent(); - - /* - * Get whether to show the 'Default' item, and the URI to play when the - * default is clicked - */ - mHasDefaultItem = intent.getBooleanExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_DEFAULT, true); - mUriForDefaultItem = intent.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI); - if (mUriForDefaultItem == null) { - mUriForDefaultItem = Settings.System.DEFAULT_RINGTONE_URI; - } - - if (savedInstanceState != null) { - mClickedPos = savedInstanceState.getInt(SAVE_CLICKED_POS, -1); - } - // Get whether to show the 'Silent' item - mHasSilentItem = intent.getBooleanExtra(RingtoneManager.EXTRA_RINGTONE_SHOW_SILENT, true); - - // Give the Activity so it can do managed queries - mRingtoneManager = new RingtoneManager(this); - - // Get whether to include DRM ringtones - boolean includeDrm = intent.getBooleanExtra(RingtoneManager.EXTRA_RINGTONE_INCLUDE_DRM, - true); - mRingtoneManager.setIncludeDrm(includeDrm); - - // Get the types of ringtones to show - int types = intent.getIntExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, -1); - if (types != -1) { - mRingtoneManager.setType(types); - } - - mCursor = mRingtoneManager.getCursor(); - - // The volume keys will control the stream that we are choosing a ringtone for - setVolumeControlStream(mRingtoneManager.inferStreamType()); - - // Get the URI whose list item should have a checkmark - mExistingUri = intent - .getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI); - - final AlertController.AlertParams p = mAlertParams; - p.mCursor = mCursor; - p.mOnClickListener = mRingtoneClickListener; - p.mLabelColumn = MediaStore.Audio.Media.TITLE; - p.mIsSingleChoice = true; - p.mOnItemSelectedListener = this; - p.mPositiveButtonText = getString(com.android.internal.R.string.ok); - p.mPositiveButtonListener = this; - p.mNegativeButtonText = getString(com.android.internal.R.string.cancel); - p.mPositiveButtonListener = this; - p.mOnPrepareListViewListener = this; - - p.mTitle = intent.getCharSequenceExtra(RingtoneManager.EXTRA_RINGTONE_TITLE); - if (p.mTitle == null) { - p.mTitle = getString(com.android.internal.R.string.ringtone_picker_title); - } - - setupAlert(); - } - - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putInt(SAVE_CLICKED_POS, mClickedPos); - } - - public void onPrepareListView(ListView listView) { - - if (mHasDefaultItem) { - mDefaultRingtonePos = addDefaultRingtoneItem(listView); - - if (RingtoneManager.isDefault(mExistingUri)) { - mClickedPos = mDefaultRingtonePos; - } - } - - if (mHasSilentItem) { - mSilentPos = addSilentItem(listView); - - // The 'Silent' item should use a null Uri - if (mExistingUri == null) { - mClickedPos = mSilentPos; - } - } - - if (mClickedPos == -1) { - mClickedPos = getListPosition(mRingtoneManager.getRingtonePosition(mExistingUri)); - } - - // Put a checkmark next to an item. - mAlertParams.mCheckedItem = mClickedPos; - } - - /** - * Adds a static item to the top of the list. A static item is one that is not from the - * RingtoneManager. - * - * @param listView The ListView to add to. - * @param textResId The resource ID of the text for the item. - * @return The position of the inserted item. - */ - private int addStaticItem(ListView listView, int textResId) { - TextView textView = (TextView) getLayoutInflater().inflate( - com.android.internal.R.layout.select_dialog_singlechoice_holo, listView, false); - textView.setText(textResId); - listView.addHeaderView(textView); - mStaticItemCount++; - return listView.getHeaderViewsCount() - 1; - } - - private int addDefaultRingtoneItem(ListView listView) { - return addStaticItem(listView, com.android.internal.R.string.ringtone_default); - } - - private int addSilentItem(ListView listView) { - return addStaticItem(listView, com.android.internal.R.string.ringtone_silent); - } - - /* - * On click of Ok/Cancel buttons - */ - public void onClick(DialogInterface dialog, int which) { - boolean positiveResult = which == DialogInterface.BUTTON_POSITIVE; - - // Stop playing the previous ringtone - mRingtoneManager.stopPreviousRingtone(); - - if (positiveResult) { - Intent resultIntent = new Intent(); - Uri uri = null; - - if (mClickedPos == mDefaultRingtonePos) { - // Set it to the default Uri that they originally gave us - uri = mUriForDefaultItem; - } else if (mClickedPos == mSilentPos) { - // A null Uri is for the 'Silent' item - uri = null; - } else { - uri = mRingtoneManager.getRingtoneUri(getRingtoneManagerPosition(mClickedPos)); - } - - resultIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI, uri); - setResult(RESULT_OK, resultIntent); - } else { - setResult(RESULT_CANCELED); - } - - getWindow().getDecorView().post(new Runnable() { - public void run() { - mCursor.deactivate(); - } - }); - - finish(); - } - - /* - * On item selected via keys - */ - public void onItemSelected(AdapterView parent, View view, int position, long id) { - playRingtone(position, DELAY_MS_SELECTION_PLAYED); - } - - public void onNothingSelected(AdapterView parent) { - } - - private void playRingtone(int position, int delayMs) { - mHandler.removeCallbacks(this); - mSampleRingtonePos = position; - mHandler.postDelayed(this, delayMs); - } - - public void run() { - - if (mSampleRingtonePos == mSilentPos) { - mRingtoneManager.stopPreviousRingtone(); - return; - } - - /* - * Stop the default ringtone, if it's playing (other ringtones will be - * stopped by the RingtoneManager when we get another Ringtone from it. - */ - if (mDefaultRingtone != null && mDefaultRingtone.isPlaying()) { - mDefaultRingtone.stop(); - mDefaultRingtone = null; - } - - Ringtone ringtone; - if (mSampleRingtonePos == mDefaultRingtonePos) { - if (mDefaultRingtone == null) { - mDefaultRingtone = RingtoneManager.getRingtone(this, mUriForDefaultItem); - } - ringtone = mDefaultRingtone; - - /* - * Normally the non-static RingtoneManager.getRingtone stops the - * previous ringtone, but we're getting the default ringtone outside - * of the RingtoneManager instance, so let's stop the previous - * ringtone manually. - */ - mRingtoneManager.stopPreviousRingtone(); - - } else { - ringtone = mRingtoneManager.getRingtone(getRingtoneManagerPosition(mSampleRingtonePos)); - } - - if (ringtone != null) { - ringtone.play(); - } - } - - @Override - protected void onStop() { - super.onStop(); - stopAnyPlayingRingtone(); - } - - @Override - protected void onPause() { - super.onPause(); - stopAnyPlayingRingtone(); - } - - private void stopAnyPlayingRingtone() { - - if (mDefaultRingtone != null && mDefaultRingtone.isPlaying()) { - mDefaultRingtone.stop(); - } - - if (mRingtoneManager != null) { - mRingtoneManager.stopPreviousRingtone(); - } - } - - private int getRingtoneManagerPosition(int listPos) { - return listPos - mStaticItemCount; - } - - private int getListPosition(int ringtoneManagerPos) { - - // If the manager position is -1 (for not found), return that - if (ringtoneManagerPos < 0) return ringtoneManagerPos; - - return ringtoneManagerPos + mStaticItemCount; - } - -} diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java index 61866e5..48ed561 100644 --- a/core/java/com/android/internal/content/PackageHelper.java +++ b/core/java/com/android/internal/content/PackageHelper.java @@ -67,8 +67,8 @@ public class PackageHelper { return null; } - public static String createSdDir(int sizeMb, String cid, - String sdEncKey, int uid) { + public static String createSdDir(int sizeMb, String cid, String sdEncKey, int uid, + boolean isExternal) { // Create mount point via MountService IMountService mountService = getMountService(); @@ -76,8 +76,8 @@ public class PackageHelper { Log.i(TAG, "Size of container " + sizeMb + " MB"); try { - int rc = mountService.createSecureContainer( - cid, sizeMb, "fat", sdEncKey, uid); + int rc = mountService.createSecureContainer(cid, sizeMb, "ext4", sdEncKey, uid, + isExternal); if (rc != StorageResultCode.OperationSucceeded) { Log.e(TAG, "Failed to create secure container " + cid); return null; @@ -206,10 +206,21 @@ public class PackageHelper { return false; } - public static void extractPublicFiles(String packagePath, File publicZipFile) + public static int extractPublicFiles(String packagePath, File publicZipFile) throws IOException { - final FileOutputStream fstr = new FileOutputStream(publicZipFile); - final ZipOutputStream publicZipOutStream = new ZipOutputStream(fstr); + final FileOutputStream fstr; + final ZipOutputStream publicZipOutStream; + + if (publicZipFile == null) { + fstr = null; + publicZipOutStream = null; + } else { + fstr = new FileOutputStream(publicZipFile); + publicZipOutStream = new ZipOutputStream(fstr); + } + + int size = 0; + try { final ZipFile privateZip = new ZipFile(packagePath); try { @@ -219,25 +230,29 @@ public class PackageHelper { if ("AndroidManifest.xml".equals(zipEntryName) || "resources.arsc".equals(zipEntryName) || zipEntryName.startsWith("res/")) { - copyZipEntry(zipEntry, privateZip, publicZipOutStream); + size += zipEntry.getSize(); + if (publicZipFile != null) { + copyZipEntry(zipEntry, privateZip, publicZipOutStream); + } } } } finally { - try { - privateZip.close(); - } catch (IOException e) { - } + try { privateZip.close(); } catch (IOException e) {} } - publicZipOutStream.finish(); - publicZipOutStream.flush(); - FileUtils.sync(fstr); - publicZipOutStream.close(); - FileUtils.setPermissions(publicZipFile.getAbsolutePath(), FileUtils.S_IRUSR - | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1); + if (publicZipFile != null) { + publicZipOutStream.finish(); + publicZipOutStream.flush(); + FileUtils.sync(fstr); + publicZipOutStream.close(); + FileUtils.setPermissions(publicZipFile.getAbsolutePath(), FileUtils.S_IRUSR + | FileUtils.S_IWUSR | FileUtils.S_IRGRP | FileUtils.S_IROTH, -1, -1); + } } finally { IoUtils.closeQuietly(publicZipOutStream); } + + return size; } private static void copyZipEntry(ZipEntry zipEntry, ZipFile inZipFile, @@ -265,4 +280,18 @@ public class PackageHelper { IoUtils.closeQuietly(data); } } + + public static boolean fixSdPermissions(String cid, int gid, String filename) { + try { + int rc = getMountService().fixPermissionsSecureContainer(cid, gid, filename); + if (rc != StorageResultCode.OperationSucceeded) { + Log.i(TAG, "Failed to fixperms container " + cid); + return false; + } + return true; + } catch (RemoteException e) { + Log.e(TAG, "Failed to fixperms container " + cid + " with exception " + e); + } + return false; + } } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index e1b9d55..60d2159 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1658,16 +1658,6 @@ android:excludeFromRecents="true" android:process=":ui"> </activity> - <activity android:name="com.android.internal.app.RingtonePickerActivity" - android:theme="@style/Theme.Holo.Dialog.Alert" - android:excludeFromRecents="true" - android:multiprocess="true" - android:process=":ui"> - <intent-filter> - <action android:name="android.intent.action.RINGTONE_PICKER" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> - </activity> <activity android:name="android.accounts.ChooseAccountActivity" android:excludeFromRecents="true" diff --git a/core/tests/coretests/src/android/content/pm/PackageHelperTests.java b/core/tests/coretests/src/android/content/pm/PackageHelperTests.java index 27112a6..7ad35d0 100644 --- a/core/tests/coretests/src/android/content/pm/PackageHelperTests.java +++ b/core/tests/coretests/src/android/content/pm/PackageHelperTests.java @@ -81,7 +81,8 @@ public class PackageHelperTests extends AndroidTestCase { public void testMountAndPullSdCard() { try { fullId = PREFIX; - fullId2 = PackageHelper.createSdDir(1024, fullId, "none", android.os.Process.myUid()); + fullId2 = PackageHelper.createSdDir(1024, fullId, "none", android.os.Process.myUid(), + true); Log.d(TAG,PackageHelper.getSdDir(fullId)); PackageHelper.unMountSdDir(fullId); diff --git a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java index 580b4da..8a5f8bb 100755 --- a/core/tests/coretests/src/android/content/pm/PackageManagerTests.java +++ b/core/tests/coretests/src/android/content/pm/PackageManagerTests.java @@ -309,9 +309,7 @@ public class PackageManagerTests extends AndroidTestCase { private static final int INSTALL_LOC_ERR = -1; private int getInstallLoc(int flags, int expInstallLocation, long pkgLen) { // Flags explicitly over ride everything else. - if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0 ) { - return INSTALL_LOC_INT; - } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0 ) { + if ((flags & PackageManager.INSTALL_EXTERNAL) != 0 ) { return INSTALL_LOC_SD; } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { return INSTALL_LOC_INT; @@ -380,61 +378,76 @@ public class PackageManagerTests extends AndroidTestCase { String publicSrcPath = publicSrcDir.getParent(); long pkgLen = new File(info.sourceDir).length(); - if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { - assertTrue((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); - assertEquals(srcPath, drmInstallPath); - assertEquals(publicSrcPath, appInstallPath); - assertTrue(info.nativeLibraryDir.startsWith(dataDir.getPath())); - } else { - assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); - int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen); - if (rLoc == INSTALL_LOC_INT) { - assertEquals(srcPath, appInstallPath); - assertEquals(publicSrcPath, appInstallPath); - assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); - assertTrue(info.nativeLibraryDir.startsWith(dataDir.getPath())); - - // Make sure the native library dir is not a symlink - final File nativeLibDir = new File(info.nativeLibraryDir); - assertTrue("Native library dir should exist at " + info.nativeLibraryDir, - nativeLibDir.exists()); - try { - assertEquals("Native library dir should not be a symlink", - info.nativeLibraryDir, - nativeLibDir.getCanonicalPath()); - } catch (IOException e) { - fail("Can't read " + nativeLibDir.getPath()); - } - } else if (rLoc == INSTALL_LOC_SD){ - assertTrue("Application flags (" + info.flags - + ") should contain FLAG_EXTERNAL_STORAGE", - (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); + int rLoc = getInstallLoc(flags, expInstallLocation, pkgLen); + if (rLoc == INSTALL_LOC_INT) { + if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { + assertTrue("The application should be installed forward locked", + (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); assertTrue("The APK path (" + srcPath + ") should start with " - + SECURE_CONTAINERS_PREFIX, srcPath - .startsWith(SECURE_CONTAINERS_PREFIX)); + + SECURE_CONTAINERS_PREFIX, + srcPath.startsWith(SECURE_CONTAINERS_PREFIX)); assertTrue("The public APK path (" + publicSrcPath + ") should start with " - + SECURE_CONTAINERS_PREFIX, publicSrcPath - .startsWith(SECURE_CONTAINERS_PREFIX)); + + SECURE_CONTAINERS_PREFIX, + publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX)); assertTrue("The native library path (" + info.nativeLibraryDir + ") should start with " + SECURE_CONTAINERS_PREFIX, info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX)); + } else { + assertFalse((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); + assertEquals(srcPath, appInstallPath); + assertEquals(publicSrcPath, appInstallPath); + assertTrue(info.nativeLibraryDir.startsWith(dataDir.getPath())); + } + assertFalse((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); - // Make sure the native library in /data/data/<app>/lib is a - // symlink to the ASEC - final File nativeLibSymLink = new File(info.dataDir, "lib"); - assertTrue("Native library symlink should exist at " + nativeLibSymLink.getPath(), - nativeLibSymLink.exists()); - try { - assertEquals(nativeLibSymLink.getPath() + " should be a symlink to " - + info.nativeLibraryDir, info.nativeLibraryDir, nativeLibSymLink - .getCanonicalPath()); - } catch (IOException e) { - fail("Can't read " + nativeLibSymLink.getPath()); - } + // Make sure the native library dir is not a symlink + final File nativeLibDir = new File(info.nativeLibraryDir); + assertTrue("Native library dir should exist at " + info.nativeLibraryDir, + nativeLibDir.exists()); + try { + assertEquals("Native library dir should not be a symlink", + info.nativeLibraryDir, + nativeLibDir.getCanonicalPath()); + } catch (IOException e) { + fail("Can't read " + nativeLibDir.getPath()); + } + } else if (rLoc == INSTALL_LOC_SD){ + if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { + assertTrue("The application should be installed forward locked", + (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); } else { - // TODO handle error. Install should have failed. - fail("Install should have failed"); + assertFalse("The application should not be installed forward locked", + (info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0); + } + assertTrue("Application flags (" + info.flags + + ") should contain FLAG_EXTERNAL_STORAGE", + (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0); + // Might need to check: + // ((info.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0) + assertTrue("The APK path (" + srcPath + ") should start with " + + SECURE_CONTAINERS_PREFIX, srcPath.startsWith(SECURE_CONTAINERS_PREFIX)); + assertTrue("The public APK path (" + publicSrcPath + ") should start with " + + SECURE_CONTAINERS_PREFIX, + publicSrcPath.startsWith(SECURE_CONTAINERS_PREFIX)); + assertTrue("The native library path (" + info.nativeLibraryDir + + ") should start with " + SECURE_CONTAINERS_PREFIX, + info.nativeLibraryDir.startsWith(SECURE_CONTAINERS_PREFIX)); + + // Make sure the native library in /data/data/<app>/lib is a + // symlink to the ASEC + final File nativeLibSymLink = new File(info.dataDir, "lib"); + assertTrue("Native library symlink should exist at " + nativeLibSymLink.getPath(), + nativeLibSymLink.exists()); + try { + assertEquals(nativeLibSymLink.getPath() + " should be a symlink to " + + info.nativeLibraryDir, info.nativeLibraryDir, nativeLibSymLink + .getCanonicalPath()); + } catch (IOException e) { + fail("Can't read " + nativeLibSymLink.getPath()); } + } else { + // TODO handle error. Install should have failed. + fail("Install should have failed"); } } catch (NameNotFoundException e) { failStr("failed with exception : " + e); @@ -1774,15 +1787,17 @@ public class PackageManagerTests extends AndroidTestCase { } /* - * Install an app with both external and forward-lock flags set. should fail + * Install an app with both external and forward-lock flags set. */ @LargeTest public void testFlagEF() { - installFromRawResource("install.apk", R.raw.install, - PackageManager.INSTALL_FORWARD_LOCK | PackageManager.INSTALL_EXTERNAL, - false, - true, PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION, - PackageInfo.INSTALL_LOCATION_AUTO); + // Do not run on devices with emulated external storage. + if (Environment.isExternalStorageEmulated()) { + return; + } + + sampleInstallFromRawResource(PackageManager.INSTALL_FORWARD_LOCK + | PackageManager.INSTALL_EXTERNAL, true); } /* @@ -1899,15 +1914,20 @@ public class PackageManagerTests extends AndroidTestCase { PackageManager.INSTALL_FORWARD_LOCK, true, false, -1, - PackageInfo.INSTALL_LOCATION_PREFER_EXTERNAL); + PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY); } /* * Install an app with fwd locked flag set and install location set to - * preferExternal. should install internally. + * preferExternal. Should install externally. */ @LargeTest public void testFlagFManifestE() { + // Do not run on devices with emulated external storage. + if (Environment.isExternalStorageEmulated()) { + return; + } + installFromRawResource("install.apk", R.raw.install_loc_sdcard, PackageManager.INSTALL_FORWARD_LOCK, true, @@ -1916,11 +1936,16 @@ public class PackageManagerTests extends AndroidTestCase { } /* - * Install an app with fwd locked flag set and install location set to - * auto. should install internally. + * Install an app with fwd locked flag set and install location set to auto. + * should install externally. */ @LargeTest public void testFlagFManifestA() { + // Do not run on devices with emulated external storage. + if (Environment.isExternalStorageEmulated()) { + return; + } + installFromRawResource("install.apk", R.raw.install_loc_auto, PackageManager.INSTALL_FORWARD_LOCK, true, diff --git a/core/tests/coretests/src/android/os/storage/AsecTests.java b/core/tests/coretests/src/android/os/storage/AsecTests.java index 5efbd88..abb8eae 100755 --- a/core/tests/coretests/src/android/os/storage/AsecTests.java +++ b/core/tests/coretests/src/android/os/storage/AsecTests.java @@ -27,20 +27,13 @@ import android.util.Log; import java.io.File; import java.io.FileOutputStream; -import junit.framework.Assert; - public class AsecTests extends AndroidTestCase { + private static final String SECURE_CONTAINER_PREFIX = "com.android.unittests.AsecTests."; private static final boolean localLOGV = true; public static final String TAG="AsecTests"; - void failStr(String errMsg) { - Log.w(TAG, "errMsg="+errMsg); - } - - void failStr(Exception e) { - Log.w(TAG, "e.getMessage="+e.getMessage()); - Log.w(TAG, "e="+e); - } + private static final String FS_FAT = "fat"; + private static final String FS_EXT4 = "ext4"; @Override protected void setUp() throws Exception { @@ -61,7 +54,9 @@ public class AsecTests extends AndroidTestCase { String[] containers = ms.getSecureContainerList(); for (int i = 0; i < containers.length; i++) { - if (containers[i].startsWith("com.android.unittests.AsecTests.")) { + if (containers[i].startsWith(SECURE_CONTAINER_PREFIX)) { + if (localLOGV) + Log.i(TAG, "Cleaning: " + containers[i]); ms.destroySecureContainer(containers[i], true); } } @@ -70,7 +65,7 @@ public class AsecTests extends AndroidTestCase { private boolean containerExists(String localId) throws RemoteException { IMountService ms = getMs(); String[] containers = ms.getSecureContainerList(); - String fullId = "com.android.unittests.AsecTests." + localId; + String fullId = SECURE_CONTAINER_PREFIX + localId; for (int i = 0; i < containers.length; i++) { if (containers[i].equals(fullId)) { @@ -80,50 +75,52 @@ public class AsecTests extends AndroidTestCase { return false; } - private int createContainer(String localId, int size, String key) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId = "com.android.unittests.AsecTests." + localId; + private int createContainer(String localId, int size, String key, String filesystem, + boolean isExternal) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId = SECURE_CONTAINER_PREFIX + localId; IMountService ms = getMs(); - return ms.createSecureContainer(fullId, size, "fat", key, android.os.Process.myUid()); + return ms.createSecureContainer(fullId, size, filesystem, key, android.os.Process.myUid(), + isExternal); } - private int mountContainer(String localId, String key) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId = "com.android.unittests.AsecTests." + localId; + private int mountContainer(String localId, String key) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId = SECURE_CONTAINER_PREFIX + localId; IMountService ms = getMs(); return ms.mountSecureContainer(fullId, key, android.os.Process.myUid()); } - private int renameContainer(String localId1, String localId2) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId1 = "com.android.unittests.AsecTests." + localId1; - String fullId2 = "com.android.unittests.AsecTests." + localId2; + private int renameContainer(String localId1, String localId2) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId1 = SECURE_CONTAINER_PREFIX + localId1; + String fullId2 = SECURE_CONTAINER_PREFIX + localId2; IMountService ms = getMs(); return ms.renameSecureContainer(fullId1, fullId2); } - private int unmountContainer(String localId, boolean force) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId = "com.android.unittests.AsecTests." + localId; + private int unmountContainer(String localId, boolean force) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId = SECURE_CONTAINER_PREFIX + localId; IMountService ms = getMs(); return ms.unmountSecureContainer(fullId, force); } - private int destroyContainer(String localId, boolean force) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId = "com.android.unittests.AsecTests." + localId; + private int destroyContainer(String localId, boolean force) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId = SECURE_CONTAINER_PREFIX + localId; IMountService ms = getMs(); return ms.destroySecureContainer(fullId, force); } - private boolean isContainerMounted(String localId) throws RemoteException { - Assert.assertTrue(isMediaMounted()); - String fullId = "com.android.unittests.AsecTests." + localId; + private boolean isContainerMounted(String localId) throws Exception { + assertTrue("Media should be mounted", isMediaMounted()); + String fullId = SECURE_CONTAINER_PREFIX + localId; IMountService ms = getMs(); return ms.isSecureContainerMounted(fullId); @@ -139,248 +136,392 @@ public class AsecTests extends AndroidTestCase { return null; } - private boolean isMediaMounted() { - try { + private boolean isMediaMounted() throws Exception { String mPath = Environment.getExternalStorageDirectory().toString(); String state = getMs().getVolumeState(mPath); return Environment.MEDIA_MOUNTED.equals(state); - } catch (RemoteException e) { - failStr(e); - return false; - } } - public void testCreateContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testCreateContainer", 4, "none")); - Assert.assertEquals(true, containerExists("testCreateContainer")); - } catch (Exception e) { - failStr(e); + + /* + * CREATE + */ + + public void test_Fat_External_Create_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 4, "none", FS_FAT, true)); + assertTrue(containerExists("testCreateContainer")); } - public void testCreateMinSizeContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testCreateContainer", 1, "none")); - Assert.assertEquals(true, containerExists("testCreateContainer")); - } catch (Exception e) { - failStr(e); + public void test_Ext4_External_Create_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 4, "none", FS_EXT4, true)); + assertTrue(containerExists("testCreateContainer")); } - public void testCreateZeroSizeContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationFailedInternalError, - createContainer("testCreateZeroContainer", 0, "none")); - } catch (Exception e) { - failStr(e); - } + public void test_Fat_Internal_Create_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 4, "none", FS_FAT, false)); + assertTrue(containerExists("testCreateContainer")); } - public void testCreateDuplicateContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testCreateDupContainer", 4, "none")); + public void test_Ext4_Internal_Create_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 4, "none", FS_EXT4, false)); + assertTrue(containerExists("testCreateContainer")); + } - Assert.assertEquals(StorageResultCode.OperationFailedInternalError, - createContainer("testCreateDupContainer", 4, "none")); - } catch (Exception e) { - failStr(e); + + /* + * CREATE MIN SIZE + */ + + public void test_Fat_External_CreateMinSize_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 1, "none", FS_FAT, true)); + assertTrue(containerExists("testCreateContainer")); } - public void testDestroyContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testDestroyContainer", 4, "none")); - Assert.assertEquals(StorageResultCode.OperationSucceeded, - destroyContainer("testDestroyContainer", false)); - } catch (Exception e) { - failStr(e); + public void test_Ext4_External_CreateMinSize_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 1, "none", FS_EXT4, true)); + assertTrue(containerExists("testCreateContainer")); } - public void testMountContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testMountContainer", 4, "none")); + public void test_Fat_Internal_CreateMinSize_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 1, "none", FS_FAT, false)); + assertTrue(containerExists("testCreateContainer")); + } - Assert.assertEquals(StorageResultCode.OperationSucceeded, - unmountContainer("testMountContainer", false)); + public void test_Ext4_Internal_CreateMinSize_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateContainer", 1, "none", FS_EXT4, false)); + assertTrue(containerExists("testCreateContainer")); + } + + + /* + * CREATE ZERO SIZE - FAIL CASE + */ - Assert.assertEquals(StorageResultCode.OperationSucceeded, - mountContainer("testMountContainer", "none")); - } catch (Exception e) { - failStr(e); + public void test_Fat_External_CreateZeroSize_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateZeroContainer", 0, "none", FS_FAT, true)); } - public void testMountBadKey() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testMountBadKey", 4, "00000000000000000000000000000000")); + public void test_Ext4_External_CreateZeroSize_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateZeroContainer", 0, "none", FS_EXT4, true)); + } - Assert.assertEquals(StorageResultCode.OperationSucceeded, - unmountContainer("testMountBadKey", false)); + public void test_Fat_Internal_CreateZeroSize_Failure() throws Exception { + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateZeroContainer", 0, "none", FS_FAT, false)); + } - Assert.assertEquals(StorageResultCode.OperationFailedInternalError, - mountContainer("testMountContainer", "000000000000000000000000000000001")); + public void test_Ext4_Internal_CreateZeroSize_Failure() throws Exception { + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateZeroContainer", 0, "none", FS_EXT4, false)); + } - Assert.assertEquals(StorageResultCode.OperationFailedInternalError, - mountContainer("testMountContainer", "none")); - } catch (Exception e) { - failStr(e); + + /* + * CREATE DUPLICATE - FAIL CASE + */ + + public void test_Fat_External_CreateDuplicate_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateDupContainer", 4, "none", FS_FAT, true)); + + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateDupContainer", 4, "none", FS_FAT, true)); } - public void testNonExistPath() { - IMountService ms = getMs(); - try { - String path = ms.getSecureContainerPath("jparks.broke.it"); - failStr(path); - } catch (IllegalArgumentException e) { - } catch (Exception e) { - failStr(e); + public void test_Ext4_External_CreateDuplicate_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateDupContainer", 4, "none", FS_EXT4, true)); + + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateDupContainer", 4, "none", FS_EXT4, true)); } - public void testUnmountBusyContainer() { - IMountService ms = getMs(); - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testUnmountBusyContainer", 4, "none")); + public void test_Fat_Internal_CreateDuplicate_Failure() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateDupContainer", 4, "none", FS_FAT, false)); + + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateDupContainer", 4, "none", FS_FAT, false)); + } + + public void test_Ext4_Internal_CreateDuplicate_Failure() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testCreateDupContainer", 4, "none", FS_EXT4, false)); - String path = ms.getSecureContainerPath("com.android.unittests.AsecTests.testUnmountBusyContainer"); + assertEquals(StorageResultCode.OperationFailedInternalError, + createContainer("testCreateDupContainer", 4, "none", FS_EXT4, false)); + } - File f = new File(path, "reference"); - FileOutputStream fos = new FileOutputStream(f); - Assert.assertEquals(StorageResultCode.OperationFailedStorageBusy, - unmountContainer("testUnmountBusyContainer", false)); + /* + * DESTROY + */ - fos.close(); - Assert.assertEquals(StorageResultCode.OperationSucceeded, - unmountContainer("testUnmountBusyContainer", false)); - } catch (Exception e) { - failStr(e); + public void test_Fat_External_Destroy_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testDestroyContainer", 4, "none", FS_FAT, true)); + assertEquals(StorageResultCode.OperationSucceeded, + destroyContainer("testDestroyContainer", false)); } - public void testDestroyBusyContainer() { - IMountService ms = getMs(); - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testDestroyBusyContainer", 4, "none")); + public void test_Ext4_External_Destroy_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testDestroyContainer", 4, "none", FS_EXT4, true)); + assertEquals(StorageResultCode.OperationSucceeded, + destroyContainer("testDestroyContainer", false)); + } - String path = ms.getSecureContainerPath("com.android.unittests.AsecTests.testDestroyBusyContainer"); + public void test_Fat_Internal_Destroy_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testDestroyContainer", 4, "none", FS_FAT, false)); + assertEquals(StorageResultCode.OperationSucceeded, + destroyContainer("testDestroyContainer", false)); + } + + public void test_Ext4_Internal_Destroy_Success() throws Exception { + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testDestroyContainer", 4, "none", FS_EXT4, false)); + assertEquals(StorageResultCode.OperationSucceeded, + destroyContainer("testDestroyContainer", false)); + } - File f = new File(path, "reference"); - FileOutputStream fos = new FileOutputStream(f); - Assert.assertEquals(StorageResultCode.OperationFailedStorageBusy, - destroyContainer("testDestroyBusyContainer", false)); + /* + * MOUNT + */ - fos.close(); - Assert.assertEquals(StorageResultCode.OperationSucceeded, - destroyContainer("testDestroyBusyContainer", false)); - } catch (Exception e) { - failStr(e); + public void test_Fat_External_Mount() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testMountContainer", 4, "none", FS_FAT, true)); + + assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testMountContainer", false)); + + assertEquals(StorageResultCode.OperationSucceeded, + mountContainer("testMountContainer", "none")); } - public void testRenameContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testRenameContainer.1", 4, "none")); - Assert.assertEquals(StorageResultCode.OperationSucceeded, - unmountContainer("testRenameContainer.1", false)); + /* + * MOUNT BAD KEY - FAIL CASE + */ + + public void test_Fat_External_MountBadKey_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testMountBadKey", 4, "00000000000000000000000000000000", FS_FAT, + true)); + + assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testMountBadKey", false)); + + assertEquals(StorageResultCode.OperationFailedInternalError, + mountContainer("testMountContainer", "000000000000000000000000000000001")); + + assertEquals(StorageResultCode.OperationFailedInternalError, + mountContainer("testMountContainer", "none")); + } - Assert.assertEquals(StorageResultCode.OperationSucceeded, - renameContainer("testRenameContainer.1", "testRenameContainer.2")); - Assert.assertEquals(false, containerExists("testRenameContainer.1")); - Assert.assertEquals(true, containerExists("testRenameContainer.2")); - } catch (Exception e) { - failStr(e); + public void test_Fat_External_UnmountBusy_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + IMountService ms = getMs(); + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testUnmountBusyContainer", 4, "none", FS_FAT, true)); + + String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX + + "testUnmountBusyContainer"); + + File f = new File(path, "reference"); + FileOutputStream fos = new FileOutputStream(f); + + assertEquals(StorageResultCode.OperationFailedStorageBusy, + unmountContainer("testUnmountBusyContainer", false)); + + fos.close(); + assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testUnmountBusyContainer", false)); } - public void testRenameSrcMountedContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testRenameContainer.1", 4, "none")); + public void test_Fat_External_DestroyBusy() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + + IMountService ms = getMs(); + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testDestroyBusyContainer", 4, "none", FS_FAT, true)); + + String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX + + "testDestroyBusyContainer"); + + File f = new File(path, "reference"); + FileOutputStream fos = new FileOutputStream(f); + + assertEquals(StorageResultCode.OperationFailedStorageBusy, + destroyContainer("testDestroyBusyContainer", false)); - Assert.assertEquals(StorageResultCode.OperationFailedStorageMounted, - renameContainer("testRenameContainer.1", "testRenameContainer.2")); - } catch (Exception e) { - failStr(e); + fos.close(); + assertEquals(StorageResultCode.OperationSucceeded, + destroyContainer("testDestroyBusyContainer", false)); + } + + public void test_Fat_External_Rename_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testRenameContainer.1", 4, "none", FS_FAT, true)); + + assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testRenameContainer.1", false)); + + assertEquals(StorageResultCode.OperationSucceeded, + renameContainer("testRenameContainer.1", "testRenameContainer.2")); + + assertFalse(containerExists("testRenameContainer.1")); + assertTrue(containerExists("testRenameContainer.2")); } - public void testRenameDstMountedContainer() { - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testRenameContainer.1", 4, "none")); + public void test_Fat_External_RenameSrcMounted_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } - Assert.assertEquals(StorageResultCode.OperationSucceeded, - unmountContainer("testRenameContainer.1", false)); + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testRenameContainer.1", 4, "none", FS_FAT, true)); - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testRenameContainer.2", 4, "none")); + assertEquals(StorageResultCode.OperationFailedStorageMounted, + renameContainer("testRenameContainer.1", "testRenameContainer.2")); + } - Assert.assertEquals(StorageResultCode.OperationFailedStorageMounted, - renameContainer("testRenameContainer.1", "testRenameContainer.2")); - } catch (Exception e) { - failStr(e); + public void test_Fat_External_RenameDstMounted_Failure() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; } + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testRenameContainer.1", 4, "none", FS_FAT, true)); + + assertEquals(StorageResultCode.OperationSucceeded, + unmountContainer("testRenameContainer.1", false)); + + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testRenameContainer.2", 4, "none", FS_FAT, true)); + + assertEquals(StorageResultCode.OperationFailedStorageMounted, + renameContainer("testRenameContainer.1", "testRenameContainer.2")); } - public void testContainerSize() { + public void test_Fat_External_Size_Success() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + IMountService ms = getMs(); - try { - Assert.assertEquals(StorageResultCode.OperationSucceeded, - createContainer("testContainerSize", 1, "none")); - String path = ms.getSecureContainerPath("com.android.unittests.AsecTests.testUnmountBusyContainer"); - - byte[] buf = new byte[4096]; - File f = new File(path, "reference"); - FileOutputStream fos = new FileOutputStream(f); - for (int i = 0; i < (1024 * 1024); i+= buf.length) { - fos.write(buf); - } - fos.close(); - } catch (Exception e) { - failStr(e); + assertEquals(StorageResultCode.OperationSucceeded, + createContainer("testContainerSize", 1, "none", FS_FAT, true)); + String path = ms.getSecureContainerPath(SECURE_CONTAINER_PREFIX + "testContainerSize"); + + byte[] buf = new byte[4096]; + File f = new File(path, "reference"); + FileOutputStream fos = new FileOutputStream(f); + for (int i = 0; i < (1024 * 1024); i += buf.length) { + fos.write(buf); } + fos.close(); + } + + public void testGetSecureContainerPath_NonExistPath_Failure() throws Exception { + IMountService ms = getMs(); + assertNull("Getting the path for an invalid container should return null", + ms.getSecureContainerPath("jparks.broke.it")); } /*------------ Tests for unmounting volume ---*/ public final long MAX_WAIT_TIME=120*1000; public final long WAIT_TIME_INCR=20*1000; - boolean getMediaState() { - try { + + boolean getMediaState() throws Exception { String mPath = Environment.getExternalStorageDirectory().toString(); String state = getMs().getVolumeState(mPath); return Environment.MEDIA_MOUNTED.equals(state); - } catch (RemoteException e) { - return false; - } } - boolean mountMedia() { + boolean mountMedia() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return true; + } + if (getMediaState()) { return true; } - try { + String mPath = Environment.getExternalStorageDirectory().toString(); int ret = getMs().mountVolume(mPath); return ret == StorageResultCode.OperationSucceeded; - } catch (RemoteException e) { - return false; - } } class StorageListener extends StorageEventListener { @@ -410,10 +551,15 @@ public class AsecTests extends AndroidTestCase { } } - private boolean unmountMedia() { + private void unmountMedia() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + if (!getMediaState()) { - return true; + return; } + String path = Environment.getExternalStorageDirectory().toString(); StorageListener observer = new StorageListener(); StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); @@ -428,17 +574,15 @@ public class AsecTests extends AndroidTestCase { waitTime += WAIT_TIME_INCR; } if(!observer.isDone()) { - throw new Exception("Timed out waiting for packageInstalled callback"); + fail("Timed out waiting for packageInstalled callback"); } - return true; } - } catch (Exception e) { - return false; } finally { sm.unregisterListener(observer); } } - public void testUnmount() { + + public void testUnmount() throws Exception { boolean oldStatus = getMediaState(); Log.i(TAG, "oldStatus="+oldStatus); try { @@ -446,7 +590,7 @@ public class AsecTests extends AndroidTestCase { if (!getMediaState()) { mountMedia(); } - assertTrue(unmountMedia()); + unmountMedia(); } finally { // Restore old status boolean currStatus = getMediaState(); @@ -472,7 +616,11 @@ public class AsecTests extends AndroidTestCase { * This test invokes unmount multiple time and expects the call back * to be invoked just once. */ - public void testUnmountMultiple() { + public void testUnmountMultiple() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + boolean oldStatus = getMediaState(); StorageManager sm = (StorageManager) mContext.getSystemService(Context.STORAGE_SERVICE); MultipleStorageLis observer = new MultipleStorageLis(); @@ -494,12 +642,10 @@ public class AsecTests extends AndroidTestCase { waitTime += WAIT_TIME_INCR; } if(!observer.isDone()) { - failStr("Timed out waiting for packageInstalled callback"); + fail("Timed out waiting for packageInstalled callback"); } } assertEquals(observer.count, 1); - } catch (Exception e) { - failStr(e); } finally { sm.unregisterListener(observer); // Restore old status @@ -514,7 +660,7 @@ public class AsecTests extends AndroidTestCase { } } } - + class ShutdownObserver extends IMountShutdownObserver.Stub{ private boolean doneFlag = false; int statusCode; @@ -536,28 +682,26 @@ public class AsecTests extends AndroidTestCase { } - boolean invokeShutdown() { + void invokeShutdown() throws Exception { IMountService ms = getMs(); ShutdownObserver observer = new ShutdownObserver(); synchronized (observer) { - try { - ms.shutdown(observer); - return true; - } catch (RemoteException e) { - failStr(e); - } + ms.shutdown(observer); } - return false; } - public void testShutdown() { + public void testShutdown() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + boolean oldStatus = getMediaState(); try { // Mount media firsts if (!getMediaState()) { mountMedia(); } - assertTrue(invokeShutdown()); + invokeShutdown(); } finally { // Restore old status boolean currStatus = getMediaState(); @@ -576,7 +720,11 @@ public class AsecTests extends AndroidTestCase { * This test invokes unmount multiple time and expects the call back * to be invoked just once. */ - public void testShutdownMultiple() { + public void testShutdownMultiple() throws Exception { + if (Environment.isExternalStorageEmulated()) { + return; + } + boolean oldStatus = getMediaState(); try { // Mount media firsts @@ -586,13 +734,9 @@ public class AsecTests extends AndroidTestCase { IMountService ms = getMs(); ShutdownObserver observer = new ShutdownObserver(); synchronized (observer) { - try { - ms.shutdown(observer); - for (int i = 0; i < 4; i++) { - ms.shutdown(null); - } - } catch (RemoteException e) { - failStr(e); + ms.shutdown(observer); + for (int i = 0; i < 4; i++) { + ms.shutdown(null); } } } finally { diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl index 768ee5e..225c11a 100644 --- a/data/keyboards/Generic.kl +++ b/data/keyboards/Generic.kl @@ -300,7 +300,7 @@ key 318 BUTTON_THUMBR # key 352 "KEY_OK" -# key 353 "KEY_SELECT" +key 353 DPAD_CENTER # key 354 "KEY_GOTO" # key 355 "KEY_CLEAR" # key 356 "KEY_POWER2" diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index c41901b..821a251b 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -31,17 +31,16 @@ import android.graphics.BitmapFactory; import android.mtp.MtpConstants; import android.net.Uri; import android.os.Environment; -import android.os.Process; import android.os.RemoteException; import android.os.SystemProperties; import android.provider.MediaStore; -import android.provider.MediaStore.Files.FileColumns; -import android.provider.Settings; import android.provider.MediaStore.Audio; +import android.provider.MediaStore.Audio.Playlists; import android.provider.MediaStore.Files; +import android.provider.MediaStore.Files.FileColumns; import android.provider.MediaStore.Images; import android.provider.MediaStore.Video; -import android.provider.MediaStore.Audio.Playlists; +import android.provider.Settings; import android.sax.Element; import android.sax.ElementListener; import android.sax.RootElement; @@ -56,10 +55,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.Locale; import libcore.io.ErrnoException; @@ -372,6 +369,14 @@ public class MediaScanner } } + private static class PlaylistEntry { + String path; + long bestmatchid; + int bestmatchlevel; + } + + private ArrayList<PlaylistEntry> mPlaylistEntries = new ArrayList<PlaylistEntry>(); + private MediaInserter mMediaInserter; private ArrayList<FileEntry> mPlayLists; @@ -1492,93 +1497,83 @@ public class MediaScanner return result; } - private boolean addPlayListEntry(String entry, String playListDirectory, - Uri uri, ContentValues values, int index, Cursor fileList) { + private boolean matchEntries(long rowId, String data) { + + int len = mPlaylistEntries.size(); + boolean done = true; + for (int i = 0; i < len; i++) { + PlaylistEntry entry = mPlaylistEntries.get(i); + if (entry.bestmatchlevel == Integer.MAX_VALUE) { + continue; // this entry has been matched already + } + done = false; + if (data.equalsIgnoreCase(entry.path)) { + entry.bestmatchid = rowId; + entry.bestmatchlevel = Integer.MAX_VALUE; + continue; // no need for path matching + } + + int matchLength = matchPaths(data, entry.path); + if (matchLength > entry.bestmatchlevel) { + entry.bestmatchid = rowId; + entry.bestmatchlevel = matchLength; + } + } + return done; + } + private void cachePlaylistEntry(String line, String playListDirectory) { + PlaylistEntry entry = new PlaylistEntry(); // watch for trailing whitespace - int entryLength = entry.length(); - while (entryLength > 0 && Character.isWhitespace(entry.charAt(entryLength - 1))) entryLength--; + int entryLength = line.length(); + while (entryLength > 0 && Character.isWhitespace(line.charAt(entryLength - 1))) entryLength--; // path should be longer than 3 characters. // avoid index out of bounds errors below by returning here. - if (entryLength < 3) return false; - if (entryLength < entry.length()) entry = entry.substring(0, entryLength); + if (entryLength < 3) return; + if (entryLength < line.length()) line = line.substring(0, entryLength); // does entry appear to be an absolute path? // look for Unix or DOS absolute paths - char ch1 = entry.charAt(0); + char ch1 = line.charAt(0); boolean fullPath = (ch1 == '/' || - (Character.isLetter(ch1) && entry.charAt(1) == ':' && entry.charAt(2) == '\\')); + (Character.isLetter(ch1) && line.charAt(1) == ':' && line.charAt(2) == '\\')); // if we have a relative path, combine entry with playListDirectory if (!fullPath) - entry = playListDirectory + entry; - + line = playListDirectory + line; + entry.path = line; //FIXME - should we look for "../" within the path? - // best matching MediaFile for the play list entry - FileEntry bestMatch = null; - - // number of rightmost file/directory names for bestMatch - int bestMatchLength = 0; - - if (fileList != null) { - int count = fileList.getCount(); - // Backing up a little in the cursor helps when the files in the - // playlist are not in the same order as they are in the database - // but are still close. - fileList.move(-1000); - while(--count >= 0) { - if (!fileList.moveToNext()) { - fileList.moveToFirst(); - } - long rowId = fileList.getLong(FILES_PRESCAN_ID_COLUMN_INDEX); - String path = fileList.getString(FILES_PRESCAN_PATH_COLUMN_INDEX); - int format = fileList.getInt(FILES_PRESCAN_FORMAT_COLUMN_INDEX); - long lastModified = fileList.getLong(FILES_PRESCAN_DATE_MODIFIED_COLUMN_INDEX); - - if (path.equalsIgnoreCase(entry)) { - bestMatch = new FileEntry(rowId, path, lastModified, format); - break; // don't bother continuing search - } + mPlaylistEntries.add(entry); + } - int matchLength = matchPaths(path, entry); - if (matchLength > bestMatchLength) { - bestMatch = new FileEntry(rowId, path, lastModified, format); - bestMatchLength = matchLength; - } + private void processCachedPlaylist(Cursor fileList, ContentValues values, Uri playlistUri) { + fileList.moveToPosition(-1); + while (fileList.moveToNext()) { + long rowId = fileList.getLong(FILES_PRESCAN_ID_COLUMN_INDEX); + String data = fileList.getString(FILES_PRESCAN_PATH_COLUMN_INDEX); + if (matchEntries(rowId, data)) { + break; } } - if (bestMatch == null) { - return false; - } - - try { - // check rowid is set. Rowid may be missing if it is inserted by bulkInsert(). - if (bestMatch.mRowId == 0) { - Cursor c = mMediaProvider.query(mAudioUri, ID_PROJECTION, - MediaStore.Files.FileColumns.DATA + "=?", - new String[] { bestMatch.mPath }, null, null); - if (c != null) { - if (c.moveToNext()) { - bestMatch.mRowId = c.getLong(0); - } - c.close(); - } - if (bestMatch.mRowId == 0) { - return false; + int len = mPlaylistEntries.size(); + int index = 0; + for (int i = 0; i < len; i++) { + PlaylistEntry entry = mPlaylistEntries.get(i); + if (entry.bestmatchlevel > 0) { + try { + values.clear(); + values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(index)); + values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, Long.valueOf(entry.bestmatchid)); + mMediaProvider.insert(playlistUri, values); + index++; + } catch (RemoteException e) { + Log.e(TAG, "RemoteException in MediaScanner.processCachedPlaylist()", e); + return; } } - // OK, now we are ready to add this to the database - values.clear(); - values.put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, Integer.valueOf(index)); - values.put(MediaStore.Audio.Playlists.Members.AUDIO_ID, Long.valueOf(bestMatch.mRowId)); - mMediaProvider.insert(uri, values); - } catch (RemoteException e) { - Log.e(TAG, "RemoteException in MediaScanner.addPlayListEntry()", e); - return false; } - - return true; + mPlaylistEntries.clear(); } private void processM3uPlayList(String path, String playListDirectory, Uri uri, @@ -1590,16 +1585,16 @@ public class MediaScanner reader = new BufferedReader( new InputStreamReader(new FileInputStream(f)), 8192); String line = reader.readLine(); - int index = 0; + mPlaylistEntries.clear(); while (line != null) { // ignore comment lines, which begin with '#' if (line.length() > 0 && line.charAt(0) != '#') { - values.clear(); - if (addPlayListEntry(line, playListDirectory, uri, values, index, fileList)) - index++; + cachePlaylistEntry(line, playListDirectory); } line = reader.readLine(); } + + processCachedPlaylist(fileList, values, uri); } } catch (IOException e) { Log.e(TAG, "IOException in MediaScanner.processM3uPlayList()", e); @@ -1622,20 +1617,19 @@ public class MediaScanner reader = new BufferedReader( new InputStreamReader(new FileInputStream(f)), 8192); String line = reader.readLine(); - int index = 0; + mPlaylistEntries.clear(); while (line != null) { // ignore comment lines, which begin with '#' if (line.startsWith("File")) { int equals = line.indexOf('='); if (equals > 0) { - values.clear(); - if (addPlayListEntry(line.substring(equals + 1), playListDirectory, - uri, values, index, fileList)) - index++; + cachePlaylistEntry(line, playListDirectory); } } line = reader.readLine(); } + + processCachedPlaylist(fileList, values, uri); } } catch (IOException e) { Log.e(TAG, "IOException in MediaScanner.processPlsPlayList()", e); @@ -1653,15 +1647,9 @@ public class MediaScanner final ContentHandler handler; String playListDirectory; - Uri uri; - Cursor fileList; - ContentValues values = new ContentValues(); - int index = 0; public WplHandler(String playListDirectory, Uri uri, Cursor fileList) { this.playListDirectory = playListDirectory; - this.uri = uri; - this.fileList = fileList; RootElement root = new RootElement("smil"); Element body = root.getChild("body"); @@ -1676,13 +1664,11 @@ public class MediaScanner public void start(Attributes attributes) { String path = attributes.getValue("", "src"); if (path != null) { - values.clear(); - if (addPlayListEntry(path, playListDirectory, uri, values, index, fileList)) { - index++; - } + cachePlaylistEntry(path, playListDirectory); } } + @Override public void end() { } @@ -1692,15 +1678,18 @@ public class MediaScanner } private void processWplPlayList(String path, String playListDirectory, Uri uri, - Cursor fileList) { + ContentValues values, Cursor fileList) { FileInputStream fis = null; try { File f = new File(path); if (f.exists()) { fis = new FileInputStream(f); + mPlaylistEntries.clear(); Xml.parse(fis, Xml.findEncodingByName("UTF-8"), new WplHandler(playListDirectory, uri, fileList).getContentHandler()); + + processCachedPlaylist(fileList, values, uri); } } catch (SAXException e) { e.printStackTrace(); @@ -1762,7 +1751,7 @@ public class MediaScanner } else if (fileType == MediaFile.FILE_TYPE_PLS) { processPlsPlayList(path, playListDirectory, membersUri, values, fileList); } else if (fileType == MediaFile.FILE_TYPE_WPL) { - processWplPlayList(path, playListDirectory, membersUri, fileList); + processWplPlayList(path, playListDirectory, membersUri, values, fileList); } } @@ -1800,7 +1789,7 @@ public class MediaScanner private native final void native_finalize(); /** - * Releases resouces associated with this MediaScanner object. + * Releases resources associated with this MediaScanner object. * It is considered good practice to call this method when * one is done using the MediaScanner object. After this method * is called, the MediaScanner object can no longer be used. diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 7aaf4aa..a5b1f45 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -393,13 +393,13 @@ public class RingtoneManager { * @return A {@link Uri} pointing to the ringtone. */ public Uri getRingtoneUri(int position) { - final Cursor cursor = getCursor(); - - if (!cursor.moveToPosition(position)) { + // use cursor directly instead of requerying it, which could easily + // cause position to shuffle. + if (mCursor == null || !mCursor.moveToPosition(position)) { return null; } - return getUriFromCursor(cursor); + return getUriFromCursor(mCursor); } private static Uri getUriFromCursor(Cursor cursor) { diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index 8e3a3c5..3eec18c 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -81,13 +81,15 @@ public class DefaultContainerService extends IntentService { * @return Returns the new cache path where the resource has been copied into * */ - public String copyResourceToContainer(final Uri packageURI, - final String cid, - final String key, final String resFileName) { + public String copyResourceToContainer(final Uri packageURI, final String cid, + final String key, final String resFileName, final String publicResFileName, + boolean isExternal, boolean isForwardLocked) { if (packageURI == null || cid == null) { return null; } - return copyResourceInner(packageURI, cid, key, resFileName); + + return copyResourceInner(packageURI, cid, key, resFileName, publicResFileName, + isExternal, isForwardLocked); } /* @@ -169,22 +171,23 @@ public class DefaultContainerService extends IntentService { } @Override - public boolean checkInternalFreeStorage(Uri packageUri, long threshold) - throws RemoteException { + public boolean checkInternalFreeStorage(Uri packageUri, boolean isForwardLocked, + long threshold) throws RemoteException { final File apkFile = new File(packageUri.getPath()); try { - return isUnderInternalThreshold(apkFile, threshold); - } catch (FileNotFoundException e) { + return isUnderInternalThreshold(apkFile, isForwardLocked, threshold); + } catch (IOException e) { return true; } } @Override - public boolean checkExternalFreeStorage(Uri packageUri) throws RemoteException { + public boolean checkExternalFreeStorage(Uri packageUri, boolean isForwardLocked) + throws RemoteException { final File apkFile = new File(packageUri.getPath()); try { - return isUnderExternalThreshold(apkFile); - } catch (FileNotFoundException e) { + return isUnderExternalThreshold(apkFile, isForwardLocked); + } catch (IOException e) { return true; } } @@ -259,12 +262,16 @@ public class DefaultContainerService extends IntentService { return mBinder; } - private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName) { - // Make sure the sdcard is mounted. - String status = Environment.getExternalStorageState(); - if (!status.equals(Environment.MEDIA_MOUNTED)) { - Slog.w(TAG, "Make sure sdcard is mounted."); - return null; + private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName, + String publicResFileName, boolean isExternal, boolean isForwardLocked) { + + if (isExternal) { + // Make sure the sdcard is mounted. + String status = Environment.getExternalStorageState(); + if (!status.equals(Environment.MEDIA_MOUNTED)) { + Slog.w(TAG, "Make sure sdcard is mounted."); + return null; + } } // The .apk file @@ -272,17 +279,18 @@ public class DefaultContainerService extends IntentService { File codeFile = new File(codePath); // Calculate size of container needed to hold base APK. - int sizeMb; + final int sizeMb; try { - sizeMb = calculateContainerSize(codeFile); - } catch (FileNotFoundException e) { - Slog.w(TAG, "File does not exist when trying to copy " + codeFile.getPath()); + sizeMb = calculateContainerSize(codeFile, isForwardLocked); + } catch (IOException e) { + Slog.w(TAG, "Problem when trying to copy " + codeFile.getPath()); return null; } // Create new container - final String newCachePath; - if ((newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid())) == null) { + final String newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid(), + isExternal); + if (newCachePath == null) { Slog.e(TAG, "Failed to create container " + newCid); return null; } @@ -303,6 +311,30 @@ public class DefaultContainerService extends IntentService { return null; } + if (isForwardLocked) { + File publicZipFile = new File(newCachePath, publicResFileName); + try { + PackageHelper.extractPublicFiles(resFile.getAbsolutePath(), publicZipFile); + if (localLOGV) { + Slog.i(TAG, "Copied resources to " + publicZipFile); + } + } catch (IOException e) { + Slog.e(TAG, "Could not chown public APK " + publicZipFile.getAbsolutePath() + ": " + + e.getMessage()); + PackageHelper.destroySdDir(newCid); + return null; + } + + try { + Libcore.os.chmod(resFile.getAbsolutePath(), 0640); + Libcore.os.chmod(publicZipFile.getAbsolutePath(), 0644); + } catch (ErrnoException e) { + Slog.e(TAG, "Could not chown APK or resource file: " + e.getMessage()); + PackageHelper.destroySdDir(newCid); + return null; + } + } + final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME); if (sharedLibraryDir.mkdir()) { int ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(codeFile, sharedLibraryDir); @@ -412,18 +444,13 @@ public class DefaultContainerService extends IntentService { int prefer; boolean checkBoth = false; + final boolean isForwardLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; + check_inner : { /* * Explicit install flags should override the manifest settings. */ - if ((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) { - /* - * Forward-locked applications cannot be installed on SD card, - * so only allow checking internal storage. - */ - prefer = PREFER_INTERNAL; - break check_inner; - } else if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { + if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { prefer = PREFER_INTERNAL; break check_inner; } else if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { @@ -473,8 +500,8 @@ public class DefaultContainerService extends IntentService { boolean fitsOnInternal = false; if (checkBoth || prefer == PREFER_INTERNAL) { try { - fitsOnInternal = isUnderInternalThreshold(apkFile, threshold); - } catch (FileNotFoundException e) { + fitsOnInternal = isUnderInternalThreshold(apkFile, isForwardLocked, threshold); + } catch (IOException e) { return PackageHelper.RECOMMEND_FAILED_INVALID_URI; } } @@ -482,8 +509,8 @@ public class DefaultContainerService extends IntentService { boolean fitsOnSd = false; if (!emulated && (checkBoth || prefer == PREFER_EXTERNAL)) { try { - fitsOnSd = isUnderExternalThreshold(apkFile); - } catch (FileNotFoundException e) { + fitsOnSd = isUnderExternalThreshold(apkFile, isForwardLocked); + } catch (IOException e) { return PackageHelper.RECOMMEND_FAILED_INVALID_URI; } } @@ -527,13 +554,17 @@ public class DefaultContainerService extends IntentService { * @return true if file fits under threshold * @throws FileNotFoundException when APK does not exist */ - private boolean isUnderInternalThreshold(File apkFile, long threshold) - throws FileNotFoundException { - final long size = apkFile.length(); + private boolean isUnderInternalThreshold(File apkFile, boolean isForwardLocked, long threshold) + throws IOException { + long size = apkFile.length(); if (size == 0 && !apkFile.exists()) { throw new FileNotFoundException(); } + if (isForwardLocked) { + size += PackageHelper.extractPublicFiles(apkFile.getAbsolutePath(), null); + } + final StatFs internalStats = new StatFs(Environment.getDataDirectory().getPath()); final long availInternalSize = (long) internalStats.getAvailableBlocks() * (long) internalStats.getBlockSize(); @@ -549,12 +580,13 @@ public class DefaultContainerService extends IntentService { * @return true if file fits * @throws IOException when file does not exist */ - private boolean isUnderExternalThreshold(File apkFile) throws FileNotFoundException { + private boolean isUnderExternalThreshold(File apkFile, boolean isForwardLocked) + throws IOException { if (Environment.isExternalStorageEmulated()) { return false; } - final int sizeMb = calculateContainerSize(apkFile); + final int sizeMb = calculateContainerSize(apkFile, isForwardLocked); final int availSdMb; if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { @@ -573,9 +605,9 @@ public class DefaultContainerService extends IntentService { * * @param apkFile file from which to calculate size * @return size in megabytes (2^20 bytes) - * @throws FileNotFoundException when file does not exist + * @throws IOException when there is a problem reading the file */ - private int calculateContainerSize(File apkFile) throws FileNotFoundException { + private int calculateContainerSize(File apkFile, boolean forwardLocked) throws IOException { // Calculate size of container needed to hold base APK. long sizeBytes = apkFile.length(); if (sizeBytes == 0 && !apkFile.exists()) { @@ -586,6 +618,10 @@ public class DefaultContainerService extends IntentService { // container size. sizeBytes += NativeLibraryHelper.sumNativeBinariesLI(apkFile); + if (forwardLocked) { + sizeBytes += PackageHelper.extractPublicFiles(apkFile.getPath(), null); + } + int sizeMb = (int) (sizeBytes >> 20); if ((sizeBytes - (sizeMb * 1024 * 1024)) > 0) { sizeMb++; diff --git a/packages/InputDevices/res/raw/keyboard_layout_croatian_and_slovenian.kcm b/packages/InputDevices/res/raw/keyboard_layout_croatian_and_slovenian.kcm new file mode 100644 index 0000000..eec9d27 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_croatian_and_slovenian.kcm @@ -0,0 +1,352 @@ +# Copyright (C) 2012 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. + +# +# Croatian and Slovenian keyboard layout, QWERTZ style. +# + +type OVERLAY + +map key 12 SLASH +map key 21 Z +map key 44 Y +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u00b8' + base: '\u0327' + shift: '\u0308' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt: '\u0303' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '\u030c' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u0302' +} + +key 4 { + label: '4' + base: '4' + shift: '$' + ralt: '\u0306' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u030a' +} + +key 6 { + label: '6' + base: '6' + shift: '&' + ralt: '\u0328' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '\u0300' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '\u0307' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: '\u0301' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '\u030b' +} + +key SLASH { + label: '\'' + base: '\'' + shift: '?' + ralt: '\u0308' +} + +key EQUALS { + label: '+' + base: '+' + shift: '*' + ralt: '\u0327' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '\\' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' + ralt: '|' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u0160' + base: '\u0161' + shift, capslock: '\u0160' + ralt: '\u00f7' +} + +key RIGHT_BRACKET { + label: '\u0110' + base: '\u0111' + shift, capslock: '\u0110' + ralt: '\u00d7' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' + ralt: '[' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' + ralt: ']' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' + ralt: '\u0268' + ralt+shift, ralt+capslock: '\u0197' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' + ralt: '\u0142' + ralt+shift, ralt+capslock: '\u0141' +} + +key SEMICOLON { + label: '\u010d' + base: '\u010c' + shift, capslock: '\u010d' +} + +key APOSTROPHE { + label: '\u0106' + base: '\u0107' + shift, capslock: '\u0106' + ralt: '\u00df' +} + +key BACKSLASH { + label: '\u017d' + base: '\u017e' + shift, capslock: '\u017d' + ralt: '\u00a4' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' + ralt: '@' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' + ralt: '{' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' + ralt: '}' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00a7' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' + ralt: '<' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' + ralt: '>' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_czech.kcm b/packages/InputDevices/res/raw/keyboard_layout_czech.kcm new file mode 100644 index 0000000..f710a8e --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_czech.kcm @@ -0,0 +1,348 @@ +# Copyright (C) 2012 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. + +# +# Czech keyboard layout. +# + +type OVERLAY + +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: ';' + base: ';' + shift: '\u00b0' +} + +key 1 { + label: '1' + base: '+' + shift: '1' + ralt: '!' +} + +key 2 { + label: '2' + base: '\u011b' + shift: '2' + ralt: '@' +} + +key 3 { + label: '3' + base: '\u0161' + shift: '3' + ralt: '#' +} + +key 4 { + label: '4' + base: '\u010d' + shift: '4' + ralt: '$' +} + +key 5 { + label: '5' + base: '\u0159' + shift: '5' + ralt: '%' +} + +key 6 { + label: '6' + base: '\u017e' + shift: '6' + ralt: '^' +} + +key 7 { + label: '7' + base: '\u00fd' + shift: '7' + ralt: '&' +} + +key 8 { + label: '8' + base: '\u00e1' + shift: '8' + ralt: '*' +} + +key 9 { + label: '9' + base: '\u00ed' + shift: '9' + ralt: '(' +} + +key 0 { + label: '0' + base: '\u00e9' + shift: '0' + ralt: ')' +} + +key MINUS { + label: '=' + base: '=' + shift: '%' + ralt: '-' + ralt+shift: '_' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u030c' + ralt: '=' + ralt+shift: '+' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00fa' + base: '\u00fa' + shift: '/' + ralt: '[' + ralt+shift: '{' +} + +key RIGHT_BRACKET { + label: ')' + base: ')' + shift: '(' + ralt: ']' + ralt+shift: '}' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u016f' + base: '\u016f' + shift: '"' + ralt: ';' + ralt+shift: ':' +} + +key APOSTROPHE { + label: '\u00a7' + base: '\u00a7' + shift: '!' + ralt: '\'' + ralt+shift: '"' +} + +key BACKSLASH { + label: '\u0308' + base: '\u0308' + shift: '\'' + ralt: '\\' + ralt+shift: '|' +} + +### ROW 4 + +key PLUS { + label: '\\' + base: '\\' + shift: '|' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' + ralt: '@' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' +} + +key COMMA { + label: ',' + base: ',' + shift: '?' + ralt: '<' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' + ralt: '>' +} + +key SLASH { + label: '-' + base: '-' + shift: '_' + ralt: '/' + ralt+shift: '?' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_danish.kcm b/packages/InputDevices/res/raw/keyboard_layout_danish.kcm new file mode 100644 index 0000000..9386a45 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_danish.kcm @@ -0,0 +1,331 @@ +# Copyright (C) 2012 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. + +# +# Danish keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u00bd' + base: '\u00bd' + shift: '\u00a7' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '\u00a4' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '+' + base: '+' + shift: '?' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u0300' + ralt: '|' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00c5' + base: '\u00e5' + shift, capslock: '\u00c5' +} + +key RIGHT_BRACKET { + label: '\u00a8' + base: '\u0308' + shift: '\u0302' + ralt: '\u0303' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00c6' + base: '\u00e6' + shift, capslock: '\u00c6' +} + +key APOSTROPHE { + label: '\u00d8' + base: '\u00f8' + shift, capslock: '\u00d8' +} + +key BACKSLASH { + label: '\'' + base: '\'' + shift: '*' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '\\' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_estonian.kcm b/packages/InputDevices/res/raw/keyboard_layout_estonian.kcm new file mode 100644 index 0000000..ef545b8 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_estonian.kcm @@ -0,0 +1,336 @@ +# Copyright (C) 2012 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. + +# +# Estonian keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u02c7' + base: '\u030c' + shift: '\u0303' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '\u00a4' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '+' + base: '+' + shift: '?' + ralt: '\\' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u0300' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00dc' + base: '\u00fc' + shift, capslock: '\u00dc' +} + +key RIGHT_BRACKET { + label: '\u00d5' + base: '\u00f5' + shift, capslock: '\u00d5' + ralt: '\u00a7' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' + ralt: '\u0161' + ralt+shift, ralt+capslock: '\u0160' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' +} + +key APOSTROPHE { + label: '\u00c4' + base: '\u00e4' + shift, capslock: '\u00c4' + ralt: '\u0302' +} + +key BACKSLASH { + label: '\'' + base: '\'' + shift: '*' + ralt: '\u00bd' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '|' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' + ralt: '\u017e' + ralt+shift, ralt+capslock: '\u017d' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_finnish.kcm b/packages/InputDevices/res/raw/keyboard_layout_finnish.kcm new file mode 100644 index 0000000..c6e5ac4 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_finnish.kcm @@ -0,0 +1,380 @@ +# Copyright (C) 2012 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. + +# +# Finnish multilingual keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u00a7' + base: '\u00a7' + shift: '\u00bd' + ralt: '\u0335' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt+shift: '\u00a1' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' + ralt+shift: '\u201d' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' + ralt+shift: '\u00bb' +} + +key 4 { + label: '4' + base: '4' + shift: '\u00a4' + ralt: '$' + ralt+shift: '\u00ab' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u2030' + ralt+shift: '\u201c' +} + +key 6 { + label: '6' + base: '6' + shift: '&' + ralt: '\u201a' + ralt+shift: '\u201e' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' + ralt+shift: '\u00b0' +} + +key SLASH { + label: '+' + base: '+' + shift: '?' + ralt: '\\' + ralt+shift: '\u00bf' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u0300' + ralt: '\u0327' + ralt+shift: '\u0328' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' + ralt: '\u00fe' + ralt+shift, ralt+capslock: '\u00de' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' + ralt: '\u0131' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' + ralt: '\u0153' + ralt+shift, ralt+capslock: '\u0152' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' + ralt: '\u031b' + ralt+shift: '\u0309' +} + +key LEFT_BRACKET { + label: '\u00c5' + base: '\u00e5' + shift, capslock: '\u00c5' + ralt: '\u030b' + ralt+shift: '\u030a' +} + +key RIGHT_BRACKET { + label: '\u00a8' + base: '\u0308' + shift: '\u0302' + ralt: '\u0303' + ralt+shift: '\u0304' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' + ralt: '\u0259' + ralt+shift, ralt+capslock: '\u018f' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' + ralt: '\u00df' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' + ralt: '\u00f0' + ralt+shift, ralt+capslock: '\u00d0' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' + ralt: '\u0138' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' + ralt: '\u0335' +} + +key SEMICOLON { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' + ralt: '\u00f8' + ralt+shift, ralt+capslock: '\u00d8' +} + +key APOSTROPHE { + label: '\u00c4' + base: '\u00e4' + shift, capslock: '\u00c4' + ralt: '\u00e6' + ralt+shift, ralt+capslock: '\u00c6' +} + +key BACKSLASH { + label: '\'' + base: '\'' + shift: '*' + ralt: '\u030c' + ralt+shift: '\u0306' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '|' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' + ralt: '\u0292' + ralt+shift, ralt+capslock: '\u01b7' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' + ralt: '\u00d7' + ralt+shift: '\u00b7' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' + ralt: '\u014b' + ralt+shift, ralt+capslock: '\u014a' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' + ralt+shift: '\u2014' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' + ralt: '\u2019' + ralt+shift: '\u2018' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' + ralt: '\u0323' + ralt+shift: '\u0307' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' + ralt: '\u2013' + ralt+shift: '\u0307' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_hungarian.kcm b/packages/InputDevices/res/raw/keyboard_layout_hungarian.kcm new file mode 100644 index 0000000..dafb50b --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_hungarian.kcm @@ -0,0 +1,362 @@ +# Copyright (C) 2012 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. + +# +# Hungarian keyboard layout, QWERTZ style. +# + +type OVERLAY + +map key 41 0 +map key 11 GRAVE +map key 12 SLASH +map key 21 Z +map key 44 Y +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key 0 { + label: '0' + base: '0' + shift: '\u00a7' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt: '\u0303' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '\u030c' +} + +key 3 { + label: '3' + base: '3' + shift: '+' + ralt: '\u0302' +} + +key 4 { + label: '4' + base: '4' + shift: '!' + ralt: '\u0306' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u030a' +} + +key 6 { + label: '6' + base: '6' + shift: '/' + ralt: '\u0328' +} + +key 7 { + label: '7' + base: '7' + shift: '=' + ralt: '\u0300' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '\u0307' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: '\u0301' +} + +key GRAVE { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' + ralt: '\u030b' +} + +key SLASH { + label: '\u00dc' + base: '\u00fc' + shift, capslock: '\u00dc' + ralt: '\u0308' +} + +key EQUALS { + label: '\u00d3' + base: '\u00f3' + shift, capslock: '\u00d3' + ralt: '\u0327' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '\\' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' + ralt: '|' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u00c4' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' + ralt: '\u20ac' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' + ralt: '\u00cd' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u0150' + base: '\u0151' + shift, capslock: '\u0150' + ralt: '\u00f7' +} + +key RIGHT_BRACKET { + label: '\u00da' + base: '\u00fa' + shift, capslock: '\u00da' + ralt: '\u00d7' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' + ralt: '\u00e4' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' + ralt: '\u0111' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' + ralt: '\u0110' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' + ralt: '[' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' + ralt: ']' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' + ralt: '\u00ed' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' + ralt: '\u0197' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' + ralt: '\u0141' +} + +key SEMICOLON { + label: '\u00c9' + base: '\u00e9' + shift, capslock: '\u00c9' + ralt: '$' +} + +key APOSTROPHE { + label: '\u00c1' + base: '\u00e1' + shift, capslock: '\u00c1' + ralt: '\u00df' +} + +key BACKSLASH { + label: '\u0170' + base: '\u0171' + shift, capslock: '\u0170' + ralt: '\u00a4' +} + +### ROW 4 + +key PLUS { + label: '\u00cd' + base: '\u00ed' + shift, capslock: '\u00cd' + ralt: '<' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' + ralt: '>' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' + ralt: '#' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' + ralt: '&' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' + ralt: '@' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' + ralt: '{' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' + ralt: '}' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: '?' + ralt: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' + ralt: '*' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_icelandic.kcm b/packages/InputDevices/res/raw/keyboard_layout_icelandic.kcm new file mode 100644 index 0000000..117f58b --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_icelandic.kcm @@ -0,0 +1,332 @@ +# Copyright (C) 2012 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. + +# +# Icelandic keyboard layout. +# + +type OVERLAY + +map key 12 EQUALS +map key 13 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u02da' + base: '\u030a' + shift: '\u0308' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' +} + +key 3 { + label: '3' + base: '3' + shift: '#' +} + +key 4 { + label: '4' + base: '4' + shift: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u20ac' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key EQUALS { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' + ralt: '\\' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '@' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u0110' + base: '\u0111' + shift, capslock: '\u0110' +} + +key RIGHT_BRACKET { + label: '\'' + base: '\'' + shift: '?' + ralt: '~' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00c6' + base: '\u00e6' + shift, capslock: '\u00c6' +} + +key APOSTROPHE { + label: '\u00b4' + base: '\u0301' + shift: '\'' + ralt: '^' +} + +key BACKSLASH { + label: '+' + base: '+' + shift: '*' + ralt: '`' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '|' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key SLASH { + label: '\u00de' + base: '\u00fe' + shift, capslock: '\u00de' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_italian.kcm b/packages/InputDevices/res/raw/keyboard_layout_italian.kcm new file mode 100644 index 0000000..bd2d25a --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_italian.kcm @@ -0,0 +1,327 @@ +# Copyright (C) 2012 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. + +# +# Italian keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\\' + base: '\\' + shift: '|' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' +} + +key 3 { + label: '3' + base: '3' + shift: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u20ac' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' +} + +key 8 { + label: '8' + base: '8' + shift: '(' +} + +key 9 { + label: '9' + base: '9' + shift: ')' +} + +key 0 { + label: '0' + base: '0' + shift: '=' +} + +key SLASH { + label: '\'' + base: '\'' + shift: '?' +} + +key EQUALS { + label: '\u00ec' + base: '\u00ec' + shift: '^' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00e8' + base: '\u00e8' + shift: '\u00e9' + ralt: '[' + ralt+shift: '{' +} + +key RIGHT_BRACKET { + label: '+' + base: '+' + shift: '*' + ralt: ']' + ralt+shift: '}' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00f2' + base: '\u00f2' + shift: '\u00e7' + ralt: '@' +} + +key APOSTROPHE { + label: '\u00e0' + base: '\u00e0' + shift: '\u00b0' + ralt: '#' +} + +key BACKSLASH { + label: '\u00f9' + base: '\u00f9' + shift: '\u00a7' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_norwegian.kcm b/packages/InputDevices/res/raw/keyboard_layout_norwegian.kcm new file mode 100644 index 0000000..d1be485 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_norwegian.kcm @@ -0,0 +1,330 @@ +# Copyright (C) 2012 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. + +# +# Norwegian keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '|' + base: '|' + shift: '\u00a7' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '\u00a4' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '+' + base: '+' + shift: '?' +} + +key EQUALS { + label: '\\' + base: '\\' + shift: '\u0300' + ralt: '\u0301' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00c5' + base: '\u00e5' + shift, capslock: '\u00c5' +} + +key RIGHT_BRACKET { + label: '\u00a8' + base: '\u0308' + shift: '\u0302' + ralt: '\u0303' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00d8' + base: '\u00f8' + shift, capslock: '\u00d8' +} + +key APOSTROPHE { + label: '\u00c6' + base: '\u00e6' + shift, capslock: '\u00c6' +} + +key BACKSLASH { + label: '\'' + base: '\'' + shift: '*' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_portuguese.kcm b/packages/InputDevices/res/raw/keyboard_layout_portuguese.kcm new file mode 100644 index 0000000..47ee867 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_portuguese.kcm @@ -0,0 +1,329 @@ +# Copyright (C) 2012 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. + +# +# Portuguese keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\\' + base: '\\' + shift: '|' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '$' + ralt: '\u00a7' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '\'' + base: '\'' + shift: '?' +} + +key EQUALS { + label: '\u00ab' + base: '\u00ab' + shift: '\u00bb' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '+' + base: '+' + shift: '*' + ralt: '\u0308' +} + +key RIGHT_BRACKET { + label: '\u00b4' + base: '\u0301' + shift: '\u0300' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00c7' + base: '\u00e7' + shift, capslock: '\u00c7' +} + +key APOSTROPHE { + label: '\u00ba' + base: '\u00ba' + shift: '\u00aa' +} + +key BACKSLASH { + label: '\u02dc' + base: '\u0303' + shift: '\u0302' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '\\' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_russian_apple.kcm b/packages/InputDevices/res/raw/keyboard_layout_russian_mac.kcm index 8c1d596..11c2ad4 100644 --- a/packages/InputDevices/res/raw/keyboard_layout_russian_apple.kcm +++ b/packages/InputDevices/res/raw/keyboard_layout_russian_mac.kcm @@ -15,7 +15,7 @@ # # Russian keyboard layout. # This is a variant of the typical Russian PC keyboard layout that is presented -# on Apple keyboards. In contrast with the standard layout, some of the symbols and +# on Mac keyboards. In contrast with the standard layout, some of the symbols and # punctuation characters have been rearranged. # As an added convenience, English characters are accessible using ralt (Alt Gr). # diff --git a/packages/InputDevices/res/raw/keyboard_layout_slovak.kcm b/packages/InputDevices/res/raw/keyboard_layout_slovak.kcm new file mode 100644 index 0000000..70c1fa4 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_slovak.kcm @@ -0,0 +1,353 @@ +# Copyright (C) 2012 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. + +# +# Slovak keyboard layout. +# + +type OVERLAY + +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: ';' + base: ';' + shift: '\u00b0' + ralt: '`' + ralt+shift: '~' +} + +key 1 { + label: '1' + base: '+' + shift: '1' + ralt: '!' +} + +key 2 { + label: '2' + base: '\u013e' + shift: '2' + ralt: '@' +} + +key 3 { + label: '3' + base: '\u0161' + shift: '3' + ralt: '#' +} + +key 4 { + label: '4' + base: '\u010d' + shift: '4' + ralt: '$' +} + +key 5 { + label: '5' + base: '\u0165' + shift: '5' + ralt: '%' +} + +key 6 { + label: '6' + base: '\u017e' + shift: '6' + ralt: '^' +} + +key 7 { + label: '7' + base: '\u00fd' + shift: '7' + ralt: '&' +} + +key 8 { + label: '8' + base: '\u00e1' + shift: '8' + ralt: '*' +} + +key 9 { + label: '9' + base: '\u00ed' + shift: '9' + ralt: '(' +} + +key 0 { + label: '0' + base: '\u00e9' + shift: '0' + ralt: ')' +} + +key MINUS { + label: '=' + base: '=' + shift: '%' + ralt: '-' + ralt+shift: '_' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u030c' + ralt: '=' + ralt+shift: '+' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '\\' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' + ralt: '|' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00fa' + base: '\u00fa' + shift: '/' + ralt: '[' + ralt+shift: '{' +} + +key RIGHT_BRACKET { + label: '\u00e4' + base: '\u00e4' + shift: '(' + ralt: ']' + ralt+shift: '}' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00f4' + base: '\u00f4' + shift: '"' + ralt: ';' + ralt+shift: ':' +} + +key APOSTROPHE { + label: '\u00a7' + base: '\u00a7' + shift: '!' + ralt: '\'' + ralt+shift: '"' +} + +key BACKSLASH { + label: '\u0148' + base: '\u0148' + shift: ')' + ralt: '\\' + ralt+shift: '|' +} + +### ROW 4 + +key PLUS { + label: '\\' + base: '\\' + shift: '|' + ralt: '&' + ralt+shift: '*' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' + ralt: '@' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key COMMA { + label: ',' + base: ',' + shift: '?' + ralt: '<' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' + ralt: '>' +} + +key SLASH { + label: '-' + base: '-' + shift: '_' + ralt: '/' + ralt+shift: '?' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_swedish.kcm b/packages/InputDevices/res/raw/keyboard_layout_swedish.kcm new file mode 100644 index 0000000..e42bd6c --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_swedish.kcm @@ -0,0 +1,331 @@ +# Copyright (C) 2012 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. + +# +# Swedish keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 53 MINUS +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u00a7' + base: '\u00a7' + shift: '\u00bd' +} + +key 1 { + label: '1' + base: '1' + shift: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '#' + ralt: '\u00a3' +} + +key 4 { + label: '4' + base: '4' + shift: '\u00a4' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '+' + base: '+' + shift: '?' + ralt: '\\' +} + +key EQUALS { + label: '\u00b4' + base: '\u0301' + shift: '\u0300' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: 'i' + shift, capslock: 'I' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u00c5' + base: '\u00e5' + shift, capslock: '\u00c5' +} + +key RIGHT_BRACKET { + label: '\u00a8' + base: '\u0308' + shift: '\u0302' + ralt: '\u0303' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' +} + +key APOSTROPHE { + label: '\u00c4' + base: '\u00e4' + shift, capslock: '\u00c4' +} + +key BACKSLASH { + label: '\'' + base: '\'' + shift: '*' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '|' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' + ralt: '\u00b5' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_turkish.kcm b/packages/InputDevices/res/raw/keyboard_layout_turkish.kcm new file mode 100644 index 0000000..e193d34 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_turkish.kcm @@ -0,0 +1,347 @@ +# Copyright (C) 2012 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. + +# +# Turkish keyboard layout. +# + +type OVERLAY + +map key 12 SLASH +map key 13 MINUS +map key 43 COMMA +map key 51 EQUALS +map key 52 BACKSLASH +map key 53 PERIOD +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '"' + base: '"' + shift: '\u00e9' + ralt: '<' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt: '>' +} + +key 2 { + label: '2' + base: '2' + shift: '\'' + ralt: '\u00a3' +} + +key 3 { + label: '3' + base: '3' + shift: '\u0302' + ralt: '#' +} + +key 4 { + label: '4' + base: '4' + shift: '+' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '\u00bd' +} + +key 6 { + label: '6' + base: '6' + shift: '&' +} + +key 7 { + label: '7' + base: '7' + shift: '/' + ralt: '{' +} + +key 8 { + label: '8' + base: '8' + shift: '(' + ralt: '[' +} + +key 9 { + label: '9' + base: '9' + shift: ')' + ralt: ']' +} + +key 0 { + label: '0' + base: '0' + shift: '=' + ralt: '}' +} + +key SLASH { + label: '*' + base: '*' + shift: '?' + ralt: '\\' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' + ralt: '|' +} + +### ROW 2 + +key Q { + label: 'Q' + base: 'q' + shift, capslock: 'Q' + ralt: '@' +} + +key W { + label: 'W' + base: 'w' + shift, capslock: 'W' +} + +key E { + label: 'E' + base: 'e' + shift, capslock: 'E' + ralt: '\u20ac' +} + +key R { + label: 'R' + base: 'r' + shift, capslock: 'R' +} + +key T { + label: 'T' + base: 't' + shift, capslock: 'T' +} + +key Y { + label: 'Y' + base: 'y' + shift, capslock: 'Y' +} + +key U { + label: 'U' + base: 'u' + shift, capslock: 'U' +} + +key I { + label: 'I' + base: '\u0131' + shift, capslock: 'I' + ralt: 'i' + ralt+shift, ralt+capslock: '\u0130' +} + +key O { + label: 'O' + base: 'o' + shift, capslock: 'O' +} + +key P { + label: 'P' + base: 'p' + shift, capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u011e' + base: '\u011f' + shift, capslock: '\u011e' + ralt: '\u0308' +} + +key RIGHT_BRACKET { + label: '\u00dc' + base: '\u00fc' + shift, capslock: '\u00dc' + ralt: '\u0303' +} + +### ROW 3 + +key A { + label: 'A' + base: 'a' + shift, capslock: 'A' + ralt: '\u00e6' + ralt+shift, ralt+capslock: '\u00c6' +} + +key S { + label: 'S' + base: 's' + shift, capslock: 'S' + ralt: '\u00df' +} + +key D { + label: 'D' + base: 'd' + shift, capslock: 'D' +} + +key F { + label: 'F' + base: 'f' + shift, capslock: 'F' +} + +key G { + label: 'G' + base: 'g' + shift, capslock: 'G' +} + +key H { + label: 'H' + base: 'h' + shift, capslock: 'H' +} + +key J { + label: 'J' + base: 'j' + shift, capslock: 'J' +} + +key K { + label: 'K' + base: 'k' + shift, capslock: 'K' +} + +key L { + label: 'L' + base: 'l' + shift, capslock: 'L' +} + +key SEMICOLON { + label: '\u015e' + base: '\u015f' + shift, capslock: '\u015e' + ralt: '\u0301' +} + +key APOSTROPHE { + label: '\u0130' + base: 'i' + shift, capslock: '\u0130' +} + +key COMMA { + label: ',' + base: ',' + shift: ';' + ralt: '\u0300' +} + +### ROW 4 + +key PLUS { + label: '<' + base: '<' + shift: '>' + ralt: '\\' +} + +key Z { + label: 'Z' + base: 'z' + shift, capslock: 'Z' +} + +key X { + label: 'X' + base: 'x' + shift, capslock: 'X' +} + +key C { + label: 'C' + base: 'c' + shift, capslock: 'C' +} + +key V { + label: 'V' + base: 'v' + shift, capslock: 'V' +} + +key B { + label: 'B' + base: 'b' + shift, capslock: 'B' +} + +key N { + label: 'N' + base: 'n' + shift, capslock: 'N' +} + +key M { + label: 'M' + base: 'm' + shift, capslock: 'M' +} + +key EQUALS { + label: '\u00d6' + base: '\u00f6' + shift, capslock: '\u00d6' +} + +key BACKSLASH { + label: '\u00c7' + base: '\u00e7' + shift, capslock: '\u00c7' +} + +key PERIOD { + label: '.' + base: '.' + shift: ':' +} diff --git a/packages/InputDevices/res/raw/keyboard_layout_ukrainian.kcm b/packages/InputDevices/res/raw/keyboard_layout_ukrainian.kcm new file mode 100644 index 0000000..a802460 --- /dev/null +++ b/packages/InputDevices/res/raw/keyboard_layout_ukrainian.kcm @@ -0,0 +1,404 @@ +# Copyright (C) 2012 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. + +# +# Ukrainian keyboard layout. +# This is a typical Ukrainian PC keyboard layout. +# As an added convenience, English characters are accessible using ralt (Alt Gr). +# + +type OVERLAY + +map key 86 PLUS + +### ROW 1 + +key GRAVE { + label: '\u0401' + base: '\u0451' + shift, capslock: '\u0401' + ralt: '`' + ralt+shift: '~' +} + +key 1 { + label: '1' + base: '1' + shift: '!' + ralt: '!' +} + +key 2 { + label: '2' + base: '2' + shift: '"' + ralt: '@' +} + +key 3 { + label: '3' + base: '3' + shift: '\u2116' + ralt: '#' +} + +key 4 { + label: '4' + base: '4' + shift: ';' + ralt: '$' +} + +key 5 { + label: '5' + base: '5' + shift: '%' + ralt: '%' +} + +key 6 { + label: '6' + base: '6' + shift: ':' + ralt: '^' +} + +key 7 { + label: '7' + base: '7' + shift: '?' + ralt: '&' +} + +key 8 { + label: '8' + base: '8' + shift: '*' + ralt: '*' +} + +key 9 { + label: '9' + base: '9' + shift: '(' + ralt: '(' +} + +key 0 { + label: '0' + base: '0' + shift: ')' + ralt: ')' +} + +key MINUS { + label: '-' + base: '-' + shift: '_' + ralt: '-' + ralt+shift: '_' +} + +key EQUALS { + label: '=' + base: '=' + shift: '+' + ralt: '=' + ralt+shift: '+' +} + +### ROW 2 + +key Q { + label: '\u0419' + base: '\u0439' + shift, capslock: '\u0419' + ralt: 'q' + ralt+shift, ralt+capslock: 'Q' +} + +key W { + label: '\u0426' + base: '\u0446' + shift, capslock: '\u0426' + ralt: 'w' + ralt+shift, ralt+capslock: 'W' +} + +key E { + label: '\u0423' + base: '\u0443' + shift, capslock: '\u0423' + ralt: 'e' + ralt+shift, ralt+capslock: 'E' +} + +key R { + label: '\u041a' + base: '\u043a' + shift, capslock: '\u041a' + ralt: 'r' + ralt+shift, ralt+capslock: 'R' +} + +key T { + label: '\u0415' + base: '\u0435' + shift, capslock: '\u0415' + ralt: 't' + ralt+shift, ralt+capslock: 'T' +} + +key Y { + label: '\u041d' + base: '\u043d' + shift, capslock: '\u041d' + ralt: 'y' + ralt+shift, ralt+capslock: 'Y' +} + +key U { + label: '\u0413' + base: '\u0433' + shift, capslock: '\u0413' + ralt: 'u' + ralt+shift, ralt+capslock: 'U' +} + +key I { + label: '\u0428' + base: '\u0448' + shift, capslock: '\u0428' + ralt: 'i' + ralt+shift, ralt+capslock: 'I' +} + +key O { + label: '\u0429' + base: '\u0449' + shift, capslock: '\u0429' + ralt: 'o' + ralt+shift, ralt+capslock: 'O' +} + +key P { + label: '\u0417' + base: '\u0437' + shift, capslock: '\u0417' + ralt: 'p' + ralt+shift, ralt+capslock: 'P' +} + +key LEFT_BRACKET { + label: '\u0425' + base: '\u0445' + shift, capslock: '\u0425' + ralt: '[' + ralt+shift: '{' +} + +key RIGHT_BRACKET { + label: '\u0407' + base: '\u0457' + shift, capslock: '\u0407' + ralt: ']' + ralt+shift: '}' +} + +### ROW 3 + +key A { + label: '\u0424' + base: '\u0444' + shift, capslock: '\u0424' + ralt: 'a' + ralt+shift, ralt+capslock: 'A' +} + +key S { + label: '\u0406' + base: '\u0456' + shift, capslock: '\u0406' + ralt: 's' + ralt+shift, ralt+capslock: 'S' +} + +key D { + label: '\u0412' + base: '\u0432' + shift, capslock: '\u0412' + ralt: 'd' + ralt+shift, ralt+capslock: 'D' +} + +key F { + label: '\u0410' + base: '\u0430' + shift, capslock: '\u0410' + ralt: 'f' + ralt+shift, ralt+capslock: 'F' +} + +key G { + label: '\u041f' + base: '\u043f' + shift, capslock: '\u041f' + ralt: 'g' + ralt+shift, ralt+capslock: 'G' +} + +key H { + label: '\u0420' + base: '\u0440' + shift, capslock: '\u0420' + ralt: 'h' + ralt+shift, ralt+capslock: 'H' +} + +key J { + label: '\u041e' + base: '\u043e' + shift, capslock: '\u041e' + ralt: 'j' + ralt+shift, ralt+capslock: 'J' +} + +key K { + label: '\u041b' + base: '\u043b' + shift, capslock: '\u041b' + ralt: 'k' + ralt+shift, ralt+capslock: 'K' +} + +key L { + label: '\u0414' + base: '\u0434' + shift, capslock: '\u0414' + ralt: 'l' + ralt+shift, ralt+capslock: 'L' +} + +key SEMICOLON { + label: '\u0416' + base: '\u0436' + shift, capslock: '\u0416' + ralt: ';' + ralt+shift: ':' +} + +key APOSTROPHE { + label: '\u0404' + base: '\u0454' + shift, capslock: '\u0404' + ralt: '\'' + ralt+shift: '"' +} + +key BACKSLASH { + label: '\\' + base: '\\' + shift: '/' + ralt: '|' +} + +### ROW 4 + +key PLUS { + label: '\u0490' + base: '\u0491' + shift, capslock: '\u0490' + ralt: '\\' + ralt+shift: '|' +} + +key Z { + label: '\u042f' + base: '\u044f' + shift, capslock: '\u042f' + ralt: 'z' + ralt+shift, ralt+capslock: 'Z' +} + +key X { + label: '\u0427' + base: '\u0447' + shift, capslock: '\u0427' + ralt: 'x' + ralt+shift, ralt+capslock: 'X' +} + +key C { + label: '\u0421' + base: '\u0441' + shift, capslock: '\u0421' + ralt: 'c' + ralt+shift, ralt+capslock: 'C' +} + +key V { + label: '\u041c' + base: '\u043c' + shift, capslock: '\u041c' + ralt: 'v' + ralt+shift, ralt+capslock: 'V' +} + +key B { + label: '\u0418' + base: '\u0438' + shift, capslock: '\u0418' + ralt: 'b' + ralt+shift, ralt+capslock: 'B' +} + +key N { + label: '\u0422' + base: '\u0442' + shift, capslock: '\u0422' + ralt: 'n' + ralt+shift, ralt+capslock: 'N' +} + +key M { + label: '\u042c' + base: '\u044c' + shift, capslock: '\u042c' + ralt: 'm' + ralt+shift, ralt+capslock: 'M' +} + +key COMMA { + label: '\u0411' + base: '\u0431' + shift, capslock: '\u0411' + ralt: ',' + ralt+shift: '<' +} + +key PERIOD { + label: '\u042e' + base: '\u044e' + shift, capslock: '\u042e' + ralt: '.' + ralt+shift: '>' +} + +key SLASH { + label: '.' + base: '.' + shift: ',' + ralt: '/' + ralt+shift: '?' +} diff --git a/packages/InputDevices/res/values/strings.xml b/packages/InputDevices/res/values/strings.xml index 95e7401..140c7d4 100644 --- a/packages/InputDevices/res/values/strings.xml +++ b/packages/InputDevices/res/values/strings.xml @@ -7,7 +7,7 @@ <string name="keyboard_layout_english_us_label">English (US)</string> <!-- US English (Dvorak style) keyboard layout label. [CHAR LIMIT=35] --> - <string name="keyboard_layout_english_us_dvorak_label">English (US), Dvorak</string> + <string name="keyboard_layout_english_us_dvorak_label">English (US), Dvorak style</string> <!-- German keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_german_label">German</string> @@ -21,8 +21,8 @@ <!-- Russian keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_russian_label">Russian</string> - <!-- Russian (Apple style) keyboard layout label. [CHAR LIMIT=35] --> - <string name="keyboard_layout_russian_apple_label">Russian, Apple</string> + <!-- Russian (Mac style) keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_russian_mac_label">Russian, Mac style</string> <!-- Spanish keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_spanish_label">Spanish</string> @@ -38,4 +38,49 @@ <!-- Bulgarian keyboard layout label. [CHAR LIMIT=35] --> <string name="keyboard_layout_bulgarian">Bulgarian</string> + + <!-- Italian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_italian">Italian</string> + + <!-- Danish keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_danish">Danish</string> + + <!-- Norwegian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_norwegian">Norwegian</string> + + <!-- Swedish keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_swedish">Swedish</string> + + <!-- Finnish keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_finnish">Finnish</string> + + <!-- Croatian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_croatian">Croatian</string> + + <!-- Czech keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_czech">Czech</string> + + <!-- Estonian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_estonian">Estonian</string> + + <!-- Hungarian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_hungarian">Hungarian</string> + + <!-- Icelandic keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_icelandic">Icelandic</string> + + <!-- Portuguese keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_portuguese">Portuguese</string> + + <!-- Slovak keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_slovak">Slovak</string> + + <!-- Slovenian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_slovenian">Slovenian</string> + + <!-- Turkish keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_turkish">Turkish</string> + + <!-- Ukrainian keyboard layout label. [CHAR LIMIT=35] --> + <string name="keyboard_layout_ukrainian">Ukrainian</string> </resources> diff --git a/packages/InputDevices/res/xml/keyboard_layouts.xml b/packages/InputDevices/res/xml/keyboard_layouts.xml index 50672a1..23f6bcb 100644 --- a/packages/InputDevices/res/xml/keyboard_layouts.xml +++ b/packages/InputDevices/res/xml/keyboard_layouts.xml @@ -24,9 +24,9 @@ android:label="@string/keyboard_layout_russian_label" android:kcm="@raw/keyboard_layout_russian" /> - <keyboard-layout android:name="keyboard_layout_russian_apple" - android:label="@string/keyboard_layout_russian_apple_label" - android:kcm="@raw/keyboard_layout_russian_apple" /> + <keyboard-layout android:name="keyboard_layout_russian_mac" + android:label="@string/keyboard_layout_russian_mac_label" + android:kcm="@raw/keyboard_layout_russian_mac" /> <keyboard-layout android:name="keyboard_layout_spanish" android:label="@string/keyboard_layout_spanish_label" @@ -47,4 +47,64 @@ <keyboard-layout android:name="keyboard_layout_bulgarian" android:label="@string/keyboard_layout_bulgarian" android:kcm="@raw/keyboard_layout_bulgarian" /> + + <keyboard-layout android:name="keyboard_layout_italian" + android:label="@string/keyboard_layout_italian" + android:kcm="@raw/keyboard_layout_italian" /> + + <keyboard-layout android:name="keyboard_layout_danish" + android:label="@string/keyboard_layout_danish" + android:kcm="@raw/keyboard_layout_danish" /> + + <keyboard-layout android:name="keyboard_layout_norwegian" + android:label="@string/keyboard_layout_norwegian" + android:kcm="@raw/keyboard_layout_norwegian" /> + + <keyboard-layout android:name="keyboard_layout_swedish" + android:label="@string/keyboard_layout_swedish" + android:kcm="@raw/keyboard_layout_swedish" /> + + <keyboard-layout android:name="keyboard_layout_finnish" + android:label="@string/keyboard_layout_finnish" + android:kcm="@raw/keyboard_layout_finnish" /> + + <keyboard-layout android:name="keyboard_layout_croatian" + android:label="@string/keyboard_layout_croatian" + android:kcm="@raw/keyboard_layout_croatian_and_slovenian" /> + + <keyboard-layout android:name="keyboard_layout_czech" + android:label="@string/keyboard_layout_czech" + android:kcm="@raw/keyboard_layout_czech" /> + + <keyboard-layout android:name="keyboard_layout_estonian" + android:label="@string/keyboard_layout_estonian" + android:kcm="@raw/keyboard_layout_estonian" /> + + <keyboard-layout android:name="keyboard_layout_hungarian" + android:label="@string/keyboard_layout_hungarian" + android:kcm="@raw/keyboard_layout_hungarian" /> + + <keyboard-layout android:name="keyboard_layout_icelandic" + android:label="@string/keyboard_layout_icelandic" + android:kcm="@raw/keyboard_layout_icelandic" /> + + <keyboard-layout android:name="keyboard_layout_portuguese" + android:label="@string/keyboard_layout_portuguese" + android:kcm="@raw/keyboard_layout_portuguese" /> + + <keyboard-layout android:name="keyboard_layout_slovak" + android:label="@string/keyboard_layout_slovak" + android:kcm="@raw/keyboard_layout_slovak" /> + + <keyboard-layout android:name="keyboard_layout_slovenian" + android:label="@string/keyboard_layout_slovenian" + android:kcm="@raw/keyboard_layout_croatian_and_slovenian" /> + + <keyboard-layout android:name="keyboard_layout_turkish" + android:label="@string/keyboard_layout_turkish" + android:kcm="@raw/keyboard_layout_turkish" /> + + <keyboard-layout android:name="keyboard_layout_ukrainian" + android:label="@string/keyboard_layout_ukrainian" + android:kcm="@raw/keyboard_layout_ukrainian" /> </keyboard-layouts> diff --git a/policy/src/com/android/internal/policy/impl/GlobalActions.java b/policy/src/com/android/internal/policy/impl/GlobalActions.java index cd6da85..3fa79b6 100644 --- a/policy/src/com/android/internal/policy/impl/GlobalActions.java +++ b/policy/src/com/android/internal/policy/impl/GlobalActions.java @@ -114,14 +114,21 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac mDeviceProvisioned = isDeviceProvisioned; if (mDialog != null) { mDialog.dismiss(); + mDialog = null; + // Show delayed, so that the dismiss of the previous dialog completes + mHandler.sendEmptyMessage(MESSAGE_SHOW); + } else { + handleShow(); } + } + + private void handleShow() { mDialog = createDialog(); prepareDialog(); mDialog.show(); mDialog.getWindow().getDecorView().setSystemUiVisibility(View.STATUS_BAR_DISABLE_EXPAND); } - /** * Create the global actions dialog. * @return A new dialog. @@ -280,7 +287,6 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac } } - /** {@inheritDoc} */ public void onDismiss(DialogInterface dialog) { if (SHOW_SILENT_TOGGLE) { @@ -694,16 +700,23 @@ class GlobalActions implements DialogInterface.OnDismissListener, DialogInterfac private static final int MESSAGE_DISMISS = 0; private static final int MESSAGE_REFRESH = 1; + private static final int MESSAGE_SHOW = 2; private static final int DIALOG_DISMISS_DELAY = 300; // ms private Handler mHandler = new Handler() { public void handleMessage(Message msg) { - if (msg.what == MESSAGE_DISMISS) { + switch (msg.what) { + case MESSAGE_DISMISS: if (mDialog != null) { mDialog.dismiss(); } - } else if (msg.what == MESSAGE_REFRESH) { + break; + case MESSAGE_REFRESH: mAdapter.notifyDataSetChanged(); + break; + case MESSAGE_SHOW: + handleShow(); + break; } } }; diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index faa8d3c..dd650bf 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -2422,15 +2422,15 @@ private NetworkStateTracker makeWimaxStateTracker() { } // Connectivity state changed: - // [31-13] Reserved for future use - // [12-9] Network subtype (for mobile network, as defined + // [31-14] Reserved for future use + // [13-10] Network subtype (for mobile network, as defined // by TelephonyManager) - // [8-3] Detailed state ordinal (as defined by + // [9-4] Detailed state ordinal (as defined by // NetworkInfo.DetailedState) - // [2-0] Network type (as defined by ConnectivityManager) - int eventLogParam = (info.getType() & 0x7) | - ((info.getDetailedState().ordinal() & 0x3f) << 3) | - (info.getSubtype() << 9); + // [3-0] Network type (as defined by ConnectivityManager) + int eventLogParam = (info.getType() & 0xf) | + ((info.getDetailedState().ordinal() & 0x3f) << 4) | + (info.getSubtype() << 10); EventLog.writeEvent(EventLogTags.CONNECTIVITY_STATE_CHANGED, eventLogParam); diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags index 249513f..41f7335 100644 --- a/services/java/com/android/server/EventLogTags.logtags +++ b/services/java/com/android/server/EventLogTags.logtags @@ -134,10 +134,10 @@ option java_package com.android.server # ConnectivityService.java # --------------------------- # Connectivity state changed: -# [31-13] Reserved for future use -# [12- 9] Network subtype (for mobile network, as defined by TelephonyManager) -# [ 8- 3] Detailed state ordinal (as defined by NetworkInfo.DetailedState) -# [ 2- 0] Network type (as defined by ConnectivityManager) +# [31-14] Reserved for future use +# [13-10] Network subtype (for mobile network, as defined by TelephonyManager) +# [ 9- 4] Detailed state ordinal (as defined by NetworkInfo.DetailedState) +# [ 3- 0] Network type (as defined by ConnectivityManager) 50020 connectivity_state_changed (custom|1|5) diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java index 510bdb2..d6606f6 100644 --- a/services/java/com/android/server/MountService.java +++ b/services/java/com/android/server/MountService.java @@ -668,6 +668,9 @@ class MountService extends IMountService.Stub updatePublicVolumeState(mExternalStoragePath, Environment.MEDIA_REMOVED); } + // Let package manager load internal ASECs. + mPms.updateExternalMediaStatus(true, false); + /* * Now that we've done our initialization, release * the hounds! @@ -1435,15 +1438,16 @@ class MountService extends IMountService.Stub } } - public int createSecureContainer(String id, int sizeMb, String fstype, - String key, int ownerUid) { + public int createSecureContainer(String id, int sizeMb, String fstype, String key, + int ownerUid, boolean external) { validatePermission(android.Manifest.permission.ASEC_CREATE); waitForReady(); warnOnNotMounted(); int rc = StorageResultCode.OperationSucceeded; try { - mConnector.execute("asec", "create", id, sizeMb, fstype, key, ownerUid); + mConnector.execute("asec", "create", id, sizeMb, fstype, key, ownerUid, + external ? "1" : "0"); } catch (NativeDaemonConnectorException e) { rc = StorageResultCode.OperationFailedInternalError; } @@ -1473,6 +1477,23 @@ class MountService extends IMountService.Stub return rc; } + public int fixPermissionsSecureContainer(String id, int gid, String filename) { + validatePermission(android.Manifest.permission.ASEC_CREATE); + warnOnNotMounted(); + + int rc = StorageResultCode.OperationSucceeded; + try { + mConnector.execute("asec", "fixperms", id, gid, filename); + /* + * Fix permissions does a remount, so no need to update + * mAsecMountSet + */ + } catch (NativeDaemonConnectorException e) { + rc = StorageResultCode.OperationFailedInternalError; + } + return rc; + } + public int destroySecureContainer(String id, boolean force) { validatePermission(android.Manifest.permission.ASEC_DESTROY); waitForReady(); diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java index 00d86e3..21ae624 100644 --- a/services/java/com/android/server/pm/PackageManagerService.java +++ b/services/java/com/android/server/pm/PackageManagerService.java @@ -723,7 +723,7 @@ public class PackageManagerService extends IPackageManager.Stub { } if (msg.obj != null) { @SuppressWarnings("unchecked") - Set<SdInstallArgs> args = (Set<SdInstallArgs>) msg.obj; + Set<AsecInstallArgs> args = (Set<AsecInstallArgs>) msg.obj; if (DEBUG_SD_INSTALL) Log.i(TAG, "Unloading all containers"); // Unload containers unloadAllContainers(args); @@ -830,17 +830,6 @@ public class PackageManagerService extends IPackageManager.Stub { } } - static boolean installOnSd(int flags) { - if (((flags & PackageManager.INSTALL_FORWARD_LOCK) != 0) || - ((flags & PackageManager.INSTALL_INTERNAL) != 0)) { - return false; - } - if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { - return true; - } - return false; - } - public static final IPackageManager main(Context context, boolean factoryTest, boolean onlyCore) { PackageManagerService m = new PackageManagerService(context, factoryTest, onlyCore); @@ -5396,7 +5385,7 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mInstallLock) { installPackageLI(args, true, res); } - args.doPostInstall(res.returnCode); + args.doPostInstall(res.returnCode, res.uid); } // A restore should be performed at this point if (a) the install @@ -5646,7 +5635,6 @@ public class PackageManagerService extends IPackageManager.Stub { */ public void handleStartCopy() throws RemoteException { int ret = PackageManager.INSTALL_SUCCEEDED; - final boolean fwdLocked = (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; final boolean onSd = (flags & PackageManager.INSTALL_EXTERNAL) != 0; final boolean onInt = (flags & PackageManager.INSTALL_INTERNAL) != 0; PackageInfoLite pkgLite = null; @@ -5655,10 +5643,6 @@ public class PackageManagerService extends IPackageManager.Stub { // Check if both bits are set. Slog.w(TAG, "Conflicting flags specified for installing on both internal and external"); ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; - } else if (fwdLocked && onSd) { - // Check for forward locked apps - Slog.w(TAG, "Cannot install fwd locked apps on sdcard"); - ret = PackageManager.INSTALL_FAILED_INVALID_INSTALL_LOCATION; } else { final long lowThreshold; @@ -5835,6 +5819,10 @@ public class PackageManagerService extends IPackageManager.Stub { mArgs = createInstallArgs(this); mRet = PackageManager.INSTALL_FAILED_INTERNAL_ERROR; } + + public boolean isForwardLocked() { + return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; + } } /* @@ -5850,14 +5838,16 @@ public class PackageManagerService extends IPackageManager.Stub { final String packageName; final InstallArgs srcArgs; final InstallArgs targetArgs; + int uid; int mRet; MoveParams(InstallArgs srcArgs, IPackageMoveObserver observer, int flags, - String packageName, String dataDir) { + String packageName, String dataDir, int uid) { this.srcArgs = srcArgs; this.observer = observer; this.flags = flags; this.packageName = packageName; + this.uid = uid; if (srcArgs != null) { Uri packageUri = Uri.fromFile(new File(srcArgs.getCodePath())); targetArgs = createInstallArgs(packageUri, flags, packageName, dataDir); @@ -5892,7 +5882,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override void handleReturnCode() { - targetArgs.doPostInstall(mRet); + targetArgs.doPostInstall(mRet, uid); int currentStatus = PackageManager.MOVE_FAILED_INTERNAL_ERROR; if (mRet == PackageManager.INSTALL_SUCCEEDED) { currentStatus = PackageManager.MOVE_SUCCEEDED; @@ -5908,9 +5898,35 @@ public class PackageManagerService extends IPackageManager.Stub { } } + /** + * Used during creation of InstallArgs + * + * @param flags package installation flags + * @return true if should be installed on external storage + */ + private static boolean installOnSd(int flags) { + if ((flags & PackageManager.INSTALL_INTERNAL) != 0) { + return false; + } + if ((flags & PackageManager.INSTALL_EXTERNAL) != 0) { + return true; + } + return false; + } + + /** + * Used during creation of InstallArgs + * + * @param flags package installation flags + * @return true if should be installed as forward locked + */ + private static boolean installForwardLocked(int flags) { + return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; + } + private InstallArgs createInstallArgs(InstallParams params) { - if (installOnSd(params.flags)) { - return new SdInstallArgs(params); + if (installOnSd(params.flags) || params.isForwardLocked()) { + return new AsecInstallArgs(params); } else { return new FileInstallArgs(params); } @@ -5918,8 +5934,9 @@ public class PackageManagerService extends IPackageManager.Stub { private InstallArgs createInstallArgs(int flags, String fullCodePath, String fullResourcePath, String nativeLibraryPath) { - if (installOnSd(flags)) { - return new SdInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath); + if (installOnSd(flags) || installForwardLocked(flags)) { + return new AsecInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath, + (flags & PackageManager.INSTALL_EXTERNAL) != 0); } else { return new FileInstallArgs(fullCodePath, fullResourcePath, nativeLibraryPath); } @@ -5927,9 +5944,10 @@ public class PackageManagerService extends IPackageManager.Stub { // Used by package mover private InstallArgs createInstallArgs(Uri packageURI, int flags, String pkgName, String dataDir) { - if (installOnSd(flags)) { - String cid = getNextCodePath(null, pkgName, "/" + SdInstallArgs.RES_FILE_NAME); - return new SdInstallArgs(packageURI, cid); + if (installOnSd(flags) || installForwardLocked(flags)) { + String cid = getNextCodePath(null, pkgName, "/" + AsecInstallArgs.RES_FILE_NAME); + return new AsecInstallArgs(packageURI, cid, + (flags & PackageManager.INSTALL_EXTERNAL) != 0); } else { return new FileInstallArgs(packageURI, pkgName, dataDir); } @@ -5956,7 +5974,8 @@ public class PackageManagerService extends IPackageManager.Stub { abstract int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException; abstract int doPreInstall(int status); abstract boolean doRename(int status, String pkgName, String oldCodePath); - abstract int doPostInstall(int status); + + abstract int doPostInstall(int status, int uid); abstract String getCodePath(); abstract String getResourcePath(); abstract String getNativeLibraryPath(); @@ -5964,6 +5983,10 @@ public class PackageManagerService extends IPackageManager.Stub { abstract void cleanUpResourcesLI(); abstract boolean doPostDeleteLI(boolean delete); abstract boolean checkFreeStorage(IMediaContainerService imcs) throws RemoteException; + + protected boolean isFwdLocked() { + return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; + } } class FileInstallArgs extends InstallArgs { @@ -6016,7 +6039,7 @@ public class PackageManagerService extends IPackageManager.Stub { try { mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); - return imcs.checkInternalFreeStorage(packageURI, lowThreshold); + return imcs.checkInternalFreeStorage(packageURI, isFwdLocked(), lowThreshold); } finally { mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); } @@ -6126,7 +6149,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } - int doPostInstall(int status) { + int doPostInstall(int status, int uid) { if (status != PackageManager.INSTALL_SUCCEEDED) { cleanUp(); } @@ -6229,10 +6252,6 @@ public class PackageManagerService extends IPackageManager.Stub { cleanUpResourcesLI(); return true; } - - private boolean isFwdLocked() { - return (flags & PackageManager.INSTALL_FORWARD_LOCK) != 0; - } } /** @@ -6246,20 +6265,23 @@ public class PackageManagerService extends IPackageManager.Stub { return subStr1.substring(sidx+1, eidx); } - class SdInstallArgs extends InstallArgs { + class AsecInstallArgs extends InstallArgs { static final String RES_FILE_NAME = "pkg.apk"; + static final String PUBLIC_RES_FILE_NAME = "res.zip"; String cid; String packagePath; + String resourcePath; String libraryPath; - SdInstallArgs(InstallParams params) { + AsecInstallArgs(InstallParams params) { super(params.packageURI, params.observer, params.flags, params.installerPackageName, params.manifestDigest); } - SdInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath) { - super(null, null, PackageManager.INSTALL_EXTERNAL, null, null); + AsecInstallArgs(String fullCodePath, String fullResourcePath, String nativeLibraryPath, + boolean isExternal) { + super(null, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null); // Extract cid from fullCodePath int eidx = fullCodePath.lastIndexOf("/"); String subStr1 = fullCodePath.substring(0, eidx); @@ -6268,14 +6290,14 @@ public class PackageManagerService extends IPackageManager.Stub { setCachePath(subStr1); } - SdInstallArgs(String cid) { - super(null, null, PackageManager.INSTALL_EXTERNAL, null, null); + AsecInstallArgs(String cid) { + super(null, null, 0, null, null); this.cid = cid; setCachePath(PackageHelper.getSdDir(cid)); } - SdInstallArgs(Uri packageURI, String cid) { - super(packageURI, null, PackageManager.INSTALL_EXTERNAL, null, null); + AsecInstallArgs(Uri packageURI, String cid, boolean isExternal) { + super(packageURI, null, isExternal ? PackageManager.INSTALL_EXTERNAL : 0, null, null); this.cid = cid; } @@ -6287,12 +6309,16 @@ public class PackageManagerService extends IPackageManager.Stub { try { mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); - return imcs.checkExternalFreeStorage(packageURI); + return imcs.checkExternalFreeStorage(packageURI, isFwdLocked()); } finally { mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); } } + private final boolean isExternal() { + return (flags & PackageManager.INSTALL_EXTERNAL) != 0; + } + int copyApk(IMediaContainerService imcs, boolean temp) throws RemoteException { if (temp) { createCopyFile(); @@ -6308,8 +6334,8 @@ public class PackageManagerService extends IPackageManager.Stub { try { mContext.grantUriPermission(DEFAULT_CONTAINER_PACKAGE, packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); - newCachePath = imcs.copyResourceToContainer(packageURI, cid, - getEncryptKey(), RES_FILE_NAME); + newCachePath = imcs.copyResourceToContainer(packageURI, cid, getEncryptKey(), + RES_FILE_NAME, PUBLIC_RES_FILE_NAME, isExternal(), isFwdLocked()); } finally { mContext.revokeUriPermission(packageURI, Intent.FLAG_GRANT_READ_URI_PERMISSION); } @@ -6329,7 +6355,7 @@ public class PackageManagerService extends IPackageManager.Stub { @Override String getResourcePath() { - return packagePath; + return resourcePath; } @Override @@ -6405,22 +6431,36 @@ public class PackageManagerService extends IPackageManager.Stub { File cachePath = new File(newCachePath); libraryPath = new File(cachePath, LIB_DIR_NAME).getPath(); packagePath = new File(cachePath, RES_FILE_NAME).getPath(); + + if (isFwdLocked()) { + resourcePath = new File(cachePath, PUBLIC_RES_FILE_NAME).getPath(); + } else { + resourcePath = packagePath; + } } - int doPostInstall(int status) { + int doPostInstall(int status, int uid) { if (status != PackageManager.INSTALL_SUCCEEDED) { cleanUp(); } else { + if (uid < Process.FIRST_APPLICATION_UID + || !PackageHelper.fixSdPermissions(cid, uid, RES_FILE_NAME)) { + Slog.e(TAG, "Failed to finalize " + cid); + PackageHelper.destroySdDir(cid); + return PackageManager.INSTALL_FAILED_CONTAINER_ERROR; + } + boolean mounted = PackageHelper.isContainerMounted(cid); if (!mounted) { - PackageHelper.mountSdDir(cid, - getEncryptKey(), Process.myUid()); + PackageHelper.mountSdDir(cid, getEncryptKey(), Process.myUid()); } } return status; } private void cleanUp() { + if (DEBUG_SD_INSTALL) Slog.i(TAG, "cleanUp"); + // Destroy secure container PackageHelper.destroySdDir(cid); } @@ -6749,8 +6789,7 @@ public class PackageManagerService extends IPackageManager.Stub { // We didn't need to disable the .apk as a current system package, // which means we are replacing another update that is already // installed. We need to make sure to delete the older one's .apk. - res.removedInfo.args = createInstallArgs(isExternal(pkg) - ? PackageManager.INSTALL_EXTERNAL : PackageManager.INSTALL_INTERNAL, + res.removedInfo.args = createInstallArgs(0, deletedPackage.applicationInfo.sourceDir, deletedPackage.applicationInfo.publicSourceDir, deletedPackage.applicationInfo.nativeLibraryDir); @@ -6836,13 +6875,9 @@ public class PackageManagerService extends IPackageManager.Stub { // Discontinue if moving dex files failed. return; } - if((res.returnCode = setPermissionsLI(newPackage)) - != PackageManager.INSTALL_SUCCEEDED) { - mInstaller.rmdex(newPackage.mScanPath); - return; - } else { - Log.d(TAG, "New package installed in " + newPackage.mPath); - } + + Log.d(TAG, "New package installed in " + newPackage.mPath); + synchronized (mPackages) { updatePermissionsLPw(newPackage.packageName, newPackage, UPDATE_PERMISSIONS_REPLACE_PKG | (newPackage.permissions.size() > 0 @@ -6872,10 +6907,9 @@ public class PackageManagerService extends IPackageManager.Stub { res.returnCode = PackageManager.INSTALL_SUCCEEDED; // Retrieve PackageSettings and parse package - int parseFlags = PackageParser.PARSE_CHATTY | - (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) | - (onSd ? PackageParser.PARSE_ON_SDCARD : 0); - parseFlags |= mDefParseFlags; + int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY + | (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0) + | (onSd ? PackageParser.PARSE_ON_SDCARD : 0); PackageParser pp = new PackageParser(tmpPackageFile.getPath()); pp.setSeparateProcesses(mSeparateProcesses); final PackageParser.Package pkg = pp.parsePackage(tmpPackageFile, @@ -6972,27 +7006,6 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private int setPermissionsLI(PackageParser.Package newPackage) { - int retCode = 0; - // TODO Gross hack but fix later. Ideally move this to be a post installation - // check after alloting uid. - if (isForwardLocked(newPackage)) { - retCode = mInstaller.setForwardLockPerm(getApkName(newPackage.mPath), - newPackage.applicationInfo.uid); - } else { - // The permissions on the resource file was set when it was copied for - // non forward locked apps and apps on sdcard - } - - if (retCode != 0) { - Slog.e(TAG, "Couldn't set new package file permissions for " + newPackage.mPath - + ". The return code was: " + retCode); - // TODO Define new internal error - return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE; - } - return PackageManager.INSTALL_SUCCEEDED; - } - private static boolean isForwardLocked(PackageParser.Package pkg) { return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_FORWARD_LOCK) != 0; } @@ -7001,6 +7014,10 @@ public class PackageManagerService extends IPackageManager.Stub { return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; } + private static boolean isExternal(PackageSetting ps) { + return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0; + } + private static boolean isSystemApp(PackageParser.Package pkg) { return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0; } @@ -8359,8 +8376,6 @@ public class PackageManagerService extends IPackageManager.Stub { // little while. mHandler.post(new Runnable() { public void run() { - // TODO fix this; this does nothing. - mHandler.removeCallbacks(this); updateExternalMediaStatusInner(mediaStatus, reportStatus); } }); @@ -8372,13 +8387,13 @@ public class PackageManagerService extends IPackageManager.Stub { * Please note that we always have to report status if reportStatus has been * set to true especially when unloading packages. */ - private void updateExternalMediaStatusInner(boolean mediaStatus, boolean reportStatus) { + private void updateExternalMediaStatusInner(boolean isMounted, boolean reportStatus) { // Collection of uids int uidArr[] = null; // Collection of stale containers HashSet<String> removeCids = new HashSet<String>(); // Collection of packages on external media with valid containers. - HashMap<SdInstallArgs, String> processCids = new HashMap<SdInstallArgs, String>(); + HashMap<AsecInstallArgs, String> processCids = new HashMap<AsecInstallArgs, String>(); // Get list of secure containers. final String list[] = PackageHelper.getSecureContainerList(); if (list == null || list.length == 0) { @@ -8391,7 +8406,7 @@ public class PackageManagerService extends IPackageManager.Stub { // reader synchronized (mPackages) { for (String cid : list) { - SdInstallArgs args = new SdInstallArgs(cid); + AsecInstallArgs args = new AsecInstallArgs(cid); if (DEBUG_SD_INSTALL) Log.i(TAG, "Processing container " + cid); String pkgName = args.getPackageName(); @@ -8441,7 +8456,7 @@ public class PackageManagerService extends IPackageManager.Stub { } } // Process packages with valid entries. - if (mediaStatus) { + if (isMounted) { if (DEBUG_SD_INSTALL) Log.i(TAG, "Loading packages"); loadMediaPackages(processCids, uidArr, removeCids); @@ -8476,12 +8491,12 @@ public class PackageManagerService extends IPackageManager.Stub { * the cid is added to list of removeCids. We currently don't delete stale * containers. */ - private void loadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[], + private void loadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], HashSet<String> removeCids) { ArrayList<String> pkgList = new ArrayList<String>(); - Set<SdInstallArgs> keys = processCids.keySet(); + Set<AsecInstallArgs> keys = processCids.keySet(); boolean doGc = false; - for (SdInstallArgs args : keys) { + for (AsecInstallArgs args : keys) { String codePath = processCids.get(args); if (DEBUG_SD_INSTALL) Log.i(TAG, "Loading container : " + args.cid); @@ -8517,7 +8532,8 @@ public class PackageManagerService extends IPackageManager.Stub { retCode = PackageManager.INSTALL_SUCCEEDED; pkgList.add(pkg.packageName); // Post process args - args.doPostInstall(PackageManager.INSTALL_SUCCEEDED); + args.doPostInstall(PackageManager.INSTALL_SUCCEEDED, + pkg.applicationInfo.uid); } } else { Slog.i(TAG, "Failed to install pkg from " + codePath + " from sdcard"); @@ -8580,9 +8596,9 @@ public class PackageManagerService extends IPackageManager.Stub { /* * Utility method to unload a list of specified containers */ - private void unloadAllContainers(Set<SdInstallArgs> cidArgs) { + private void unloadAllContainers(Set<AsecInstallArgs> cidArgs) { // Just unmount all valid containers. - for (SdInstallArgs arg : cidArgs) { + for (AsecInstallArgs arg : cidArgs) { synchronized (mInstallLock) { arg.doPostDeleteLI(false); } @@ -8598,14 +8614,14 @@ public class PackageManagerService extends IPackageManager.Stub { * that we always have to post this message if status has been requested no * matter what. */ - private void unloadMediaPackages(HashMap<SdInstallArgs, String> processCids, int uidArr[], + private void unloadMediaPackages(HashMap<AsecInstallArgs, String> processCids, int uidArr[], final boolean reportStatus) { if (DEBUG_SD_INSTALL) Log.i(TAG, "unloading media packages"); ArrayList<String> pkgList = new ArrayList<String>(); - ArrayList<SdInstallArgs> failedList = new ArrayList<SdInstallArgs>(); - final Set<SdInstallArgs> keys = processCids.keySet(); - for (SdInstallArgs args : keys) { + ArrayList<AsecInstallArgs> failedList = new ArrayList<AsecInstallArgs>(); + final Set<AsecInstallArgs> keys = processCids.keySet(); + for (AsecInstallArgs args : keys) { String pkgName = args.getPackageName(); if (DEBUG_SD_INSTALL) Log.i(TAG, "Trying to unload pkg : " + pkgName); @@ -8666,9 +8682,6 @@ public class PackageManagerService extends IPackageManager.Stub { if (pkg.applicationInfo != null && isSystemApp(pkg)) { Slog.w(TAG, "Cannot move system application"); returnCode = PackageManager.MOVE_FAILED_SYSTEM_PACKAGE; - } else if (pkg.applicationInfo != null && isForwardLocked(pkg)) { - Slog.w(TAG, "Cannot move forward locked app."); - returnCode = PackageManager.MOVE_FAILED_FORWARD_LOCKED; } else if (pkg.mOperationPending) { Slog.w(TAG, "Attempt to move package which has pending operations"); returnCode = PackageManager.MOVE_FAILED_OPERATION_PENDING; @@ -8700,13 +8713,14 @@ public class PackageManagerService extends IPackageManager.Stub { * anyway. */ if (returnCode != PackageManager.MOVE_SUCCEEDED) { - processPendingMove(new MoveParams(null, observer, 0, packageName, null), returnCode); + processPendingMove(new MoveParams(null, observer, 0, packageName, null, -1), + returnCode); } else { Message msg = mHandler.obtainMessage(INIT_COPY); InstallArgs srcArgs = createInstallArgs(currFlags, pkg.applicationInfo.sourceDir, pkg.applicationInfo.publicSourceDir, pkg.applicationInfo.nativeLibraryDir); MoveParams mp = new MoveParams(srcArgs, observer, newFlags, packageName, - pkg.applicationInfo.dataDir); + pkg.applicationInfo.dataDir, pkg.applicationInfo.uid); msg.obj = mp; mHandler.sendMessage(msg); } @@ -8831,7 +8845,8 @@ public class PackageManagerService extends IPackageManager.Stub { if (returnCode != PackageManager.MOVE_SUCCEEDED) { // Clean up failed installation if (mp.targetArgs != null) { - mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR); + mp.targetArgs.doPostInstall(PackageManager.INSTALL_FAILED_INTERNAL_ERROR, + -1); } } else { // Force a gc to clear things up. |
