diff options
author | herriojr <jherriott@cyngn.com> | 2015-09-08 13:59:20 -0700 |
---|---|---|
committer | herriojr <jherriott@cyngn.com> | 2015-09-14 14:29:43 -0700 |
commit | e78ca4d6fecbd4a52ee02fe727810593e27950c2 (patch) | |
tree | d3b3010a746a9bf8c81804e9b441e9bf310d963c /cm | |
parent | 35df988aa547c25d47975f3eaefd84cc61006647 (diff) | |
download | vendor_cmsdk-e78ca4d6fecbd4a52ee02fe727810593e27950c2.zip vendor_cmsdk-e78ca4d6fecbd4a52ee02fe727810593e27950c2.tar.gz vendor_cmsdk-e78ca4d6fecbd4a52ee02fe727810593e27950c2.tar.bz2 |
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
Diffstat (limited to 'cm')
7 files changed, 266 insertions, 0 deletions
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<ApplicationSuggestion> 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<ApplicationSuggestion> 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<ApplicationSuggestion> 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" /> + <!-- Permission for accessing a provider of app suggestions + @hide --> + <permission android:name="cyanogenmod.permission.ACCESS_APP_SUGGESTIONS" + android:label="@string/permlab_accessAppSuggestions" + android:description="@string/permdesc_accessAppSuggestions" + android:protectionLevel="signature|system|development" /> + <application android:process="system" android:persistent="true" android:hasCode="false" diff --git a/cm/res/res/values/config.xml b/cm/res/res/values/config.xml new file mode 100644 index 0000000..eb8982d --- /dev/null +++ b/cm/res/res/values/config.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + 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. +--> +<resources> + <!-- Whether to enable app suggest overlay which allows app suggest + provider to be replaced by an app at run-time. When disabled, only + the config_appSuggestProviderPackageName will be searched for app + suggest provider, otherwise packages whos signature matches the + signature of config_appSuggestProviderPackageNames will be searched, + and the service with the highest version number will be picked. + Anyone who wants to disable the overlay mechanism can set it to false. + + Note: There appears to be an issue with false if we reinstall the provider which causes + it to not get the update and fail to reconnect on package update. It's safer to just + use the list version with config_appSuggestProviderPackageNames. + --> + <bool name="config_enableAppSuggestOverlay" translatable="false">true</bool> + + <!-- Package name providing app suggest support. Used only when + config_enableAppSuggestOverlay is false. --> + <string name="config_appSuggestProviderPackageName" translatable="false">com.cyanogen.app.suggest</string> + + <!-- List of packages providing app suggest support. Used only when + config_enableAppSuggestOverlay is true. --> + <string-array name="config_appSuggestProviderPackageNames" translatable="false"> + <item>com.cyanogen.app.suggest</item> + </string-array> +</resources>
\ 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 @@ <string name="permlab_managePersistentStorage">manage persistent storage</string> <string name="permdesc_managePersistentStorage">Allows an app to read or write properties which may persist thrοugh a factory reset.</string> + <!-- Labels for the ACCESS_APP_SUGGESTIONS permission --> + <string name="permlab_accessAppSuggestions">access application suggestions</string> + <string name="permdesc_accessAppSuggestions">Allows an app to access application suggestions.</string> + <!-- Label to show for a service that is running because it is observing the user's custom tiles. --> <string name="custom_tile_listener_binding_label">Custom tile listener</string> 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. --> <private-symbols package="org.cyanogenmod.platform.internal" /> + <java-symbol type="bool" name="config_enableAppSuggestOverlay"/> + <java-symbol type="string" name="config_appSuggestProviderPackageName"/> + <java-symbol type="array" name="config_appSuggestProviderPackageNames"/> + <java-symbol type="string" name="custom_tile_listener_binding_label" /> <!-- Profiles --> |