1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.googlecode.android_scripting.facade;
18
19import android.app.Service;
20import android.content.Intent;
21
22import com.googlecode.android_scripting.Log;
23import com.googlecode.android_scripting.exception.Sl4aException;
24import com.googlecode.android_scripting.jsonrpc.RpcReceiver;
25import com.googlecode.android_scripting.jsonrpc.RpcReceiverManager;
26import com.googlecode.android_scripting.rpc.RpcDeprecated;
27import com.googlecode.android_scripting.rpc.RpcMinSdk;
28
29import java.lang.reflect.InvocationTargetException;
30import java.lang.reflect.Method;
31import java.util.Collection;
32
33public class FacadeManager extends RpcReceiverManager {
34
35  private final Service mService;
36  private final Intent mIntent;
37  private int mSdkLevel;
38
39  public FacadeManager(int sdkLevel, Service service, Intent intent,
40      Collection<Class<? extends RpcReceiver>> classList) {
41    super(classList);
42    mSdkLevel = sdkLevel;
43    mService = service;
44    mIntent = intent;
45  }
46
47  public int getSdkLevel() {
48    return mSdkLevel;
49  }
50
51  public Service getService() {
52    return mService;
53  }
54
55  public Intent getIntent() {
56    return mIntent;
57  }
58
59  @Override
60  public Object invoke(Class<? extends RpcReceiver> clazz, Method method, Object[] args)
61      throws Exception {
62    try {
63      if (method.isAnnotationPresent(RpcDeprecated.class)) {
64        String replacedBy = method.getAnnotation(RpcDeprecated.class).value();
65        String title = method.getName() + " is deprecated";
66        Log.notify(mService, title, title, String.format("Please use %s instead.", replacedBy));
67      } else if (method.isAnnotationPresent(RpcMinSdk.class)) {
68        int requiredSdkLevel = method.getAnnotation(RpcMinSdk.class).value();
69        if (mSdkLevel < requiredSdkLevel) {
70          throw new Sl4aException(String.format("%s requires API level %d, current level is %d",
71              method.getName(), requiredSdkLevel, mSdkLevel));
72        }
73      }
74      return super.invoke(clazz, method, args);
75    } catch (InvocationTargetException e) {
76      if (e.getCause() instanceof SecurityException) {
77        Log.notify(mService, "RPC invoke failed...", mService.getPackageName(), e.getCause()
78            .getMessage());
79      }
80      throw e;
81    }
82  }
83
84  public AndroidFacade.Resources getAndroidFacadeResources() {
85    return new AndroidFacade.Resources() {
86      @Override
87      public int getLogo48() {
88        // TODO(Alexey): As an alternative, ask application for resource ids.
89        String packageName = mService.getApplication().getPackageName();
90        return mService.getResources().getIdentifier("script_logo_48", "drawable", packageName);
91      }
92      @Override
93      public int getStringId(String identifier) {
94        // TODO(markdr): Figure out what the TODO above wants to do.
95        String packageName = mService.getApplication().getPackageName();
96        return mService.getResources().getIdentifier(identifier, "string", packageName);
97      }
98    };
99  }
100}
101