From e78ca4d6fecbd4a52ee02fe727810593e27950c2 Mon Sep 17 00:00:00 2001 From: herriojr Date: Tue, 8 Sep 2015 13:59:20 -0700 Subject: Added Application Suggestions. Added in custom Resolver to handle providing suggestions. Added in Service to handle providing suggestions to custom resolver. Added in ability to provider suggestions through a Proxy to another application which must be installed during compile time if one is to be used. This is a similar implementation to how the Location Services work. Change-Id: Id960260596b7bb6485caa1e1d07744e387a4c6e9 --- .../internal/AppSuggestManagerService.java | 76 +++++++++++++++ .../internal/AppSuggestProviderInterface.java | 32 +++++++ .../platform/internal/AppSuggestProviderProxy.java | 102 +++++++++++++++++++++ cm/res/AndroidManifest.xml | 7 ++ cm/res/res/values/config.xml | 41 +++++++++ cm/res/res/values/strings.xml | 4 + cm/res/res/values/symbols.xml | 4 + 7 files changed, 266 insertions(+) create mode 100644 cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestManagerService.java create mode 100644 cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestProviderInterface.java create mode 100644 cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestProviderProxy.java create mode 100644 cm/res/res/values/config.xml (limited to 'cm') diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestManagerService.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestManagerService.java new file mode 100644 index 0000000..d7a6ad4 --- /dev/null +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestManagerService.java @@ -0,0 +1,76 @@ +/** + * Copyright (c) 2015, The CyanogenMod 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 org.cyanogenmod.platform.internal; + +import android.content.Context; +import android.content.Intent; +import android.os.IBinder; +import android.util.Log; +import android.util.Slog; +import com.android.server.SystemService; + +import cyanogenmod.app.CMContextConstants; +import cyanogenmod.app.suggest.ApplicationSuggestion; +import cyanogenmod.app.suggest.IAppSuggestManager; +import cyanogenmod.platform.Manifest; + +import java.util.ArrayList; +import java.util.List; + +public class AppSuggestManagerService extends SystemService { + private static final String TAG = "AppSgstMgrService"; + public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); + + public static final String NAME = "appsuggest"; + + public static final String ACTION = "org.cyanogenmod.app.suggest"; + + private AppSuggestProviderInterface mImpl; + + private final IBinder mService = new IAppSuggestManager.Stub() { + public boolean handles(Intent intent) { + if (mImpl == null) return false; + + return mImpl.handles(intent); + } + + public List getSuggestions(Intent intent) { + if (mImpl == null) return new ArrayList<>(0); + + return mImpl.getSuggestions(intent); + } + }; + + public AppSuggestManagerService(Context context) { + super(context); + } + + @Override + public void onStart() { + mImpl = AppSuggestProviderProxy.createAndBind(mContext, TAG, ACTION, + R.bool.config_enableAppSuggestOverlay, + R.string.config_appSuggestProviderPackageName, + R.array.config_appSuggestProviderPackageNames); + if (mImpl == null) { + Slog.e(TAG, "no app suggest provider found"); + } else { + Slog.i(TAG, "Bound to to suggest provider"); + } + + publishBinderService(CMContextConstants.CM_APP_SUGGEST_SERVICE, mService); + } +} diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestProviderInterface.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestProviderInterface.java new file mode 100644 index 0000000..da815ce --- /dev/null +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestProviderInterface.java @@ -0,0 +1,32 @@ +/** + * Copyright (c) 2015, The CyanogenMod 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 org.cyanogenmod.platform.internal; + +import android.content.Intent; +import cyanogenmod.app.suggest.ApplicationSuggestion; + +import java.util.List; + +/** + * App Suggestion Manager's interface for Applicaiton Suggestion Providers. + * + * @hide + */ +public interface AppSuggestProviderInterface { + boolean handles(Intent intent); + List getSuggestions(Intent intent); +} diff --git a/cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestProviderProxy.java b/cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestProviderProxy.java new file mode 100644 index 0000000..0357f73 --- /dev/null +++ b/cm/lib/main/java/org/cyanogenmod/platform/internal/AppSuggestProviderProxy.java @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2015, The CyanogenMod 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 org.cyanogenmod.platform.internal; + +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.RemoteException; +import android.util.Log; +import com.android.server.ServiceWatcher; + +import cyanogenmod.app.suggest.ApplicationSuggestion; +import cyanogenmod.app.suggest.IAppSuggestProvider; + +import java.util.ArrayList; +import java.util.List; + +/** + * @hide + */ +public class AppSuggestProviderProxy implements AppSuggestProviderInterface { + private static final String TAG = AppSuggestProviderProxy.class.getSimpleName(); + private static final boolean DEBUG = AppSuggestManagerService.DEBUG; + + public static AppSuggestProviderProxy createAndBind( + Context context, String name, String action, + int overlaySwitchResId, int defaultServicePackageNameResId, + int initialPackageNamesResId) { + AppSuggestProviderProxy proxy = new AppSuggestProviderProxy(context, name, action, + overlaySwitchResId, defaultServicePackageNameResId, initialPackageNamesResId); + if (proxy.bind()) { + return proxy; + } else { + return null; + } + } + + private Context mContext; + private ServiceWatcher mServiceWatcher; + + private AppSuggestProviderProxy(Context context, String name, String action, + int overlaySwitchResId, int defaultServicePackageNameResId, + int initialPackageNamesResId) { + mContext = context; + mServiceWatcher = new ServiceWatcher(mContext, TAG + "-" + name, action, overlaySwitchResId, + defaultServicePackageNameResId, initialPackageNamesResId, null, null); + } + + private boolean bind() { + return mServiceWatcher.start(); + } + + private IAppSuggestProvider getService() { + return IAppSuggestProvider.Stub.asInterface(mServiceWatcher.getBinder()); + } + + @Override + public boolean handles(Intent intent) { + IAppSuggestProvider service = getService(); + if (service == null) return false; + + try { + return service.handles(intent); + } catch (RemoteException e) { + Log.w(TAG, e); + } catch (Exception e) { + // never let remote service crash system server + Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e); + } + return false; + } + + @Override + public List getSuggestions(Intent intent) { + IAppSuggestProvider service = getService(); + if (service == null) return new ArrayList<>(0); + + try { + return service.getSuggestions(intent); + } catch (RemoteException e) { + Log.w(TAG, e); + } catch (Exception e) { + // never let remote service crash system server + Log.e(TAG, "Exception from " + mServiceWatcher.getBestPackageName(), e); + } + return new ArrayList<>(0); + } +} diff --git a/cm/res/AndroidManifest.xml b/cm/res/AndroidManifest.xml index 8c40827..ec801cd 100644 --- a/cm/res/AndroidManifest.xml +++ b/cm/res/AndroidManifest.xml @@ -120,6 +120,13 @@ android:description="@string/permdesc_managePersistentStorage" android:protectionLevel="system|signature" /> + + + + + + + true + + + com.cyanogen.app.suggest + + + + com.cyanogen.app.suggest + + \ No newline at end of file diff --git a/cm/res/res/values/strings.xml b/cm/res/res/values/strings.xml index e727080..bcfed5a 100644 --- a/cm/res/res/values/strings.xml +++ b/cm/res/res/values/strings.xml @@ -70,6 +70,10 @@ manage persistent storage Allows an app to read or write properties which may persist thrοugh a factory reset. + + access application suggestions + Allows an app to access application suggestions. + Custom tile listener diff --git a/cm/res/res/values/symbols.xml b/cm/res/res/values/symbols.xml index 3dcf497..7977939 100644 --- a/cm/res/res/values/symbols.xml +++ b/cm/res/res/values/symbols.xml @@ -19,6 +19,10 @@ SDK. Instead, put them here. --> + + + + -- cgit v1.1