From 9e7f9cf9211953a2ef015ddc614e0523ca856b81 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Queru Date: Thu, 12 Nov 2009 18:46:13 -0800 Subject: eclair snapshot --- res/values-da/strings.xml | 21 +++++++++++++++++++++ res/values-el/strings.xml | 21 +++++++++++++++++++++ res/values-es-rUS/strings.xml | 21 +++++++++++++++++++++ res/values-ko/strings.xml | 21 +++++++++++++++++++++ res/values-nb/strings.xml | 21 +++++++++++++++++++++ res/values-pt-rPT/strings.xml | 21 +++++++++++++++++++++ res/values-pt/strings.xml | 21 +++++++++++++++++++++ res/values-ru/strings.xml | 21 +++++++++++++++++++++ res/values-sv/strings.xml | 21 +++++++++++++++++++++ res/values-tr/strings.xml | 21 +++++++++++++++++++++ res/values-zh-rCN/strings.xml | 21 +++++++++++++++++++++ .../providers/applications/ApplicationLauncher.java | 7 ++++++- .../applications/ApplicationsProvider.java | 9 ++++++++- 13 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 res/values-da/strings.xml create mode 100644 res/values-el/strings.xml create mode 100644 res/values-es-rUS/strings.xml create mode 100644 res/values-ko/strings.xml create mode 100644 res/values-nb/strings.xml create mode 100644 res/values-pt-rPT/strings.xml create mode 100644 res/values-pt/strings.xml create mode 100644 res/values-ru/strings.xml create mode 100644 res/values-sv/strings.xml create mode 100644 res/values-tr/strings.xml create mode 100644 res/values-zh-rCN/strings.xml diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml new file mode 100644 index 0000000..70117b7 --- /dev/null +++ b/res/values-da/strings.xml @@ -0,0 +1,21 @@ + + + + "Apps" + "Program" + "Navne på installerede programmer" + diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml new file mode 100644 index 0000000..ec58c6d --- /dev/null +++ b/res/values-el/strings.xml @@ -0,0 +1,21 @@ + + + + "Εφαρμογές" + "Εφαρμογή" + "Ονόματα εγκατεστημένων εφαρμογών" + diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml new file mode 100644 index 0000000..9062e21 --- /dev/null +++ b/res/values-es-rUS/strings.xml @@ -0,0 +1,21 @@ + + + + "Apps" + "Aplicación" + "Nombres de aplicaciones instaladas" + diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml new file mode 100644 index 0000000..66afbcc --- /dev/null +++ b/res/values-ko/strings.xml @@ -0,0 +1,21 @@ + + + + "응용프로그램" + "응용프로그램" + "설치된 응용프로그램의 이름" + diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml new file mode 100644 index 0000000..9ad7ab0 --- /dev/null +++ b/res/values-nb/strings.xml @@ -0,0 +1,21 @@ + + + + "Apps" + "Program" + "Navn på installerte programmer" + diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml new file mode 100644 index 0000000..b76d8af --- /dev/null +++ b/res/values-pt-rPT/strings.xml @@ -0,0 +1,21 @@ + + + + "Apps" + "Aplicação" + "Nomes das aplicações instaladas" + diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml new file mode 100644 index 0000000..0e1d534 --- /dev/null +++ b/res/values-pt/strings.xml @@ -0,0 +1,21 @@ + + + + "Aplicativos" + "Aplicativo" + "Nomes dos aplicativos instalados" + diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml new file mode 100644 index 0000000..a35fd61 --- /dev/null +++ b/res/values-ru/strings.xml @@ -0,0 +1,21 @@ + + + + "Приложения" + "Приложение" + "Названия установленных приложений" + diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml new file mode 100644 index 0000000..4e6da0b --- /dev/null +++ b/res/values-sv/strings.xml @@ -0,0 +1,21 @@ + + + + "Program" + "Program" + "Namn på installerade program" + diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml new file mode 100644 index 0000000..506dfb0 --- /dev/null +++ b/res/values-tr/strings.xml @@ -0,0 +1,21 @@ + + + + "Uygulamalar" + "Uygulama" + "Yüklenen uygulamaların adları" + diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml new file mode 100644 index 0000000..d0e1cac --- /dev/null +++ b/res/values-zh-rCN/strings.xml @@ -0,0 +1,21 @@ + + + + "应用程序" + "应用程序" + "已安装的应用程序的名称" + diff --git a/src/com/android/providers/applications/ApplicationLauncher.java b/src/com/android/providers/applications/ApplicationLauncher.java index 8463fb6..830597f 100644 --- a/src/com/android/providers/applications/ApplicationLauncher.java +++ b/src/com/android/providers/applications/ApplicationLauncher.java @@ -17,6 +17,7 @@ package com.android.providers.applications; import android.app.Activity; +import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Intent; import android.net.Uri; @@ -45,7 +46,11 @@ public class ApplicationLauncher extends Activity { launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); launchIntent.setComponent(componentName); - startActivity(launchIntent); + try { + startActivity(launchIntent); + } catch (ActivityNotFoundException ex) { + Log.w(TAG, "Activity not found: " + componentName); + } handled = true; } } diff --git a/src/com/android/providers/applications/ApplicationsProvider.java b/src/com/android/providers/applications/ApplicationsProvider.java index ee18a74..454681d 100644 --- a/src/com/android/providers/applications/ApplicationsProvider.java +++ b/src/com/android/providers/applications/ApplicationsProvider.java @@ -285,7 +285,14 @@ public class ApplicationsProvider extends ContentProvider implements ThreadFacto */ @Override public String getType(Uri uri) { - return SearchManager.SUGGEST_MIME_TYPE; + switch (sURIMatcher.match(uri)) { + case SEARCH_SUGGEST: + return SearchManager.SUGGEST_MIME_TYPE; + case SHORTCUT_REFRESH: + return SearchManager.SHORTCUT_MIME_TYPE; + default: + throw new IllegalArgumentException("Unknown URL " + uri); + } } /** -- cgit v1.2.3 From 8273d4fc1e0d5f87e7620eb88c5bb22b432ef002 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Tue, 12 Jan 2010 15:19:20 -0800 Subject: android-2.1_r1 snapshot --- res/values-da/strings.xml | 2 +- .../applications/ApplicationsProvider.java | 209 +++++++++++---------- 2 files changed, 106 insertions(+), 105 deletions(-) diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 70117b7..f7a3d7f 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -15,7 +15,7 @@ --> - "Apps" + "Programmer" "Program" "Navne på installerede programmer" diff --git a/src/com/android/providers/applications/ApplicationsProvider.java b/src/com/android/providers/applications/ApplicationsProvider.java index 454681d..2d92af3 100644 --- a/src/com/android/providers/applications/ApplicationsProvider.java +++ b/src/com/android/providers/applications/ApplicationsProvider.java @@ -33,19 +33,16 @@ import android.database.DatabaseUtils; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.Looper; +import android.os.Message; import android.provider.Applications; import android.text.TextUtils; import android.util.Log; import java.util.HashMap; -import java.util.LinkedList; import java.util.List; -import java.util.concurrent.Executor; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; /** * Fetches the list of applications installed on the phone to provide search suggestions. @@ -56,16 +53,22 @@ import java.util.concurrent.atomic.AtomicInteger; * to date list of installed applications. Alternatively, Launcher could be updated to use this * provider. */ -public class ApplicationsProvider extends ContentProvider implements ThreadFactory { - +public class ApplicationsProvider extends ContentProvider { + private static final boolean DBG = false; - + private static final String TAG = "ApplicationsProvider"; private static final int SEARCH_SUGGEST = 0; private static final int SHORTCUT_REFRESH = 1; private static final UriMatcher sURIMatcher = buildUriMatcher(); + private static final int THREAD_PRIORITY = android.os.Process.THREAD_PRIORITY_BACKGROUND; + + // Messages for mHandler + private static final int MSG_UPDATE = 0; + private static final int MSG_REMOVE = 1; + // TODO: Move these to android.provider.Applications? public static final String _ID = "_id"; public static final String NAME = "name"; @@ -80,12 +83,9 @@ public class ApplicationsProvider extends ContentProvider implements ThreadFacto buildSuggestionsProjectionMap(); private SQLiteDatabase mDb; - private final AtomicInteger mThreadCount = new AtomicInteger(1); - private Executor mExecutor; + // Handler that runs DB updates. + private Handler mHandler; - // mQLock protects access to the list of pending updates - private final Object mQLock = new Object(); - private final LinkedList mPending = new LinkedList(); /** * We delay application updates by this many millis to avoid doing more than one update to the @@ -112,108 +112,95 @@ public class ApplicationsProvider extends ContentProvider implements ThreadFacto public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (Intent.ACTION_PACKAGE_ADDED.equals(action) - || Intent.ACTION_PACKAGE_REMOVED.equals(action) || Intent.ACTION_PACKAGE_CHANGED.equals(action)) { - // do this in a worker thread to avoid ANRs - if (DBG) Log.d(TAG, "package update: " + intent); - postAppsUpdate(); + if (DBG) Log.d(TAG, "package added/updated: " + intent); + String packageName = getPackageName(intent); + postAppsUpdate(packageName); + } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { + if (DBG) Log.d(TAG, "package removed: " + intent); + String packageName = getPackageName(intent); + postAppsRemove(packageName); } } }; + /** + * Gets the package name from an {@link Intent.ACTION_PACKAGE_ADDED}, + * {@link Intent.ACTION_PACKAGE_CHANGED}, or {@link Intent.ACTION_PACKAGE_REMOVED} + * intent. + * + * @param intent + * @return The package name, or {@code null} if none. + */ + private String getPackageName(Intent intent) { + Uri data = intent.getData(); + if (data == null) { + Log.e(TAG, "Got intent " + intent + " with no data."); + return null; + } + String packageName = data.getSchemeSpecificPart(); + if (packageName == null) { + Log.e(TAG, "No package name in " + intent); + return null; + } + return packageName; + } + @Override public boolean onCreate() { createDatabase(); registerBroadcastReceiver(); - mExecutor = new ThreadPoolExecutor(1, 1, - 5, TimeUnit.SECONDS, - new LinkedBlockingQueue(), - this); - postAppsUpdate(); + HandlerThread thread = new HandlerThread("ApplicationsProviderUpdater", THREAD_PRIORITY); + thread.start(); + mHandler = new UpdateHandler(thread.getLooper()); + postAppsUpdate(null); return true; } - // ---------- - // BEGIN ASYC UPDATE CODE - // - only one update at a time - // - cancel any outstanding updates when a new one comes in so they become no-ops - // ---------- - - /** - * {@inheritDoc} - */ - public Thread newThread(Runnable r) { - return new WorkerThread(r, "ApplicationsProvider #" + mThreadCount.getAndIncrement()); - } + private class UpdateHandler extends Handler { - // a thread that runs with background priority - private static class WorkerThread extends Thread { - - private WorkerThread(Runnable runnable, String threadName) { - super(runnable, threadName); + public UpdateHandler(Looper looper) { + super(looper); } @Override - public void run() { - android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND); - super.run(); - } - } - - /** - * Post an update, and add it to the pending queue. Cancel any other pending operatinos. - */ - private void postAppsUpdate() { - final UpdateRunnable r = new UpdateRunnable(); - synchronized (mQLock) { - for (UpdateRunnable updateRunnable : mPending) { - updateRunnable.cancel(); + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_UPDATE: { + String packageName = (String) msg.obj; + updateApplicationsList(packageName); + break; + } + case MSG_REMOVE: { + String packageName = (String) msg.obj; + removeApplications(packageName); + break; + } + default: + Log.e(TAG, "Unknown message: " + msg.what); + break; } - mPending.add(r); - } - mExecutor.execute(r); - } - - private void doneRunning(UpdateRunnable runnable) { - synchronized (mQLock) { - mPending.remove(runnable); } } /** - * Updates the applications list, unless it was cancelled. When done, calls back to - * {@link ApplicationsProvider#doneRunning} do be removed from pending queue. + * Posts an update to run on the DB update thread. + * + * @param packageName Name of package whose activities to update. + * If {@code null}, all packages are updated. */ - class UpdateRunnable implements Runnable { - - private volatile boolean mCancelled = false; - - void cancel() { - mCancelled = true; - } - - public void run() { - - try { - Thread.sleep(UPDATE_DELAY_MILLIS); - } catch (InterruptedException e) { - // not expected, but meh - mCancelled = true; - } - - try { - if (!mCancelled) { - updateApplicationsList(); - } else if (DBG) { - Log.d(TAG, "avoided applications update."); + private void postAppsUpdate(String packageName) { + Message msg = Message.obtain(); + msg.what = MSG_UPDATE; + msg.obj = packageName; + mHandler.sendMessageDelayed(msg, UPDATE_DELAY_MILLIS); + } - } - } catch (Exception e) { - Log.e(TAG, "error updating applications list.", e); - } finally { - doneRunning(this); - } - } + private void postAppsRemove(String packageName) { + Message msg = Message.obtain(); + msg.what = MSG_REMOVE; + msg.obj = packageName; + mHandler.sendMessageDelayed(msg, UPDATE_DELAY_MILLIS); } // ---------- @@ -411,13 +398,12 @@ public class ApplicationsProvider extends ContentProvider implements ThreadFacto /** * Updates the cached list of installed applications. + * + * @param packageName Name of package whose activities to update. + * If {@code null}, all packages are updated. */ - private void updateApplicationsList() { - // TODO: Instead of rebuilding the whole list on every change, - // just add, remove or update the application that has changed. - // Adding and updating seem tricky, since I can't see an easy way to list the - // launchable activities in a given package. - if (DBG) Log.d(TAG, "Updating database..."); + private void updateApplicationsList(String packageName) { + if (DBG) Log.d(TAG, "Updating database (packageName = " + packageName + ")..."); DatabaseUtils.InsertHelper inserter = new DatabaseUtils.InsertHelper(mDb, APPLICATIONS_TABLE); @@ -426,16 +412,23 @@ public class ApplicationsProvider extends ContentProvider implements ThreadFacto int packageCol = inserter.getColumnIndex(PACKAGE); int classCol = inserter.getColumnIndex(CLASS); int iconCol = inserter.getColumnIndex(ICON); - + mDb.beginTransaction(); try { - mDb.execSQL("DELETE FROM " + APPLICATIONS_TABLE); + removeApplications(packageName); String description = getContext().getString(R.string.application_desc); // Iterate and find all the activities which have the LAUNCHER category set. Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); + if (packageName != null) { + // Limit to activities in the package, if given + mainIntent.setPackage(packageName); + } final PackageManager manager = getContext().getPackageManager(); - for (ResolveInfo info : manager.queryIntentActivities(mainIntent, 0)) { + List activities = manager.queryIntentActivities(mainIntent, 0); + int activityCount = activities == null ? 0 : activities.size(); + for (int i = 0; i < activityCount; i++) { + ResolveInfo info = activities.get(i); String title = info.loadLabel(manager).toString(); if (TextUtils.isEmpty(title)) { title = info.activityInfo.name; @@ -468,7 +461,15 @@ public class ApplicationsProvider extends ContentProvider implements ThreadFacto if (DBG) Log.d(TAG, "Finished updating database."); } - + private void removeApplications(String packageName) { + if (packageName == null) { + mDb.delete(APPLICATIONS_TABLE, null, null); + } else { + mDb.delete(APPLICATIONS_TABLE, PACKAGE + " = ?", new String[] { packageName }); + } + + } + @Override public Uri insert(Uri uri, ContentValues values) { throw new UnsupportedOperationException(); -- cgit v1.2.3