| /* |
| * Copyright (C) 2015 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.google.services.creators; |
| |
| import com.android.tools.idea.structure.services.DeveloperServiceCreator; |
| import com.android.tools.idea.structure.services.ServiceContext; |
| import com.android.tools.idea.ui.properties.BindingsManager; |
| import com.android.tools.idea.ui.properties.InvalidationListener; |
| import com.android.tools.idea.ui.properties.Observable; |
| import com.android.tools.idea.ui.properties.collections.ObservableList; |
| import com.android.tools.idea.ui.properties.core.BoolValueProperty; |
| import com.android.tools.idea.ui.properties.core.IntValueProperty; |
| import com.android.tools.idea.ui.properties.core.ObservableBool; |
| import com.android.tools.idea.ui.properties.core.StringValueProperty; |
| import com.android.tools.idea.ui.properties.expressions.bool.BooleanExpression; |
| import com.android.tools.idea.ui.properties.expressions.bool.BooleanExpressions; |
| import com.android.tools.idea.ui.properties.expressions.list.AbstractMapExpression; |
| import com.android.tools.idea.ui.properties.expressions.list.SizeExpression; |
| import com.android.tools.idea.ui.properties.expressions.string.IsEmptyExpression; |
| import com.google.api.client.http.javanet.NetHttpTransport; |
| import com.google.api.client.json.jackson2.JacksonFactory; |
| import com.google.api.services.analytics.Analytics; |
| import com.google.api.services.analytics.model.Account; |
| import com.google.api.services.analytics.model.Accounts; |
| import com.google.api.services.analytics.model.Webproperties; |
| import com.google.api.services.analytics.model.Webproperty; |
| import com.google.gct.login.CredentialedUser; |
| import com.google.gct.login.GoogleLogin; |
| import com.google.services.GoogleServiceCreators; |
| import com.google.services.GoogleServiceLoginListener; |
| import com.intellij.util.Consumer; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.util.concurrent.Callable; |
| |
| public final class AnalyticsServiceCreator extends DeveloperServiceCreator { |
| |
| private final ObservableBool myLoggedIn = GoogleServiceLoginListener.getInstance().loggedIn(); |
| private final ObservableList<Account> myAccounts = new ObservableList<Account>(); |
| private final ObservableList<Webproperty> myProperties = new ObservableList<Webproperty>(); |
| private final IntValueProperty myAccountIndex = new IntValueProperty(-1); |
| private final IntValueProperty myPropertyIndex = new IntValueProperty(-1); |
| private final StringValueProperty myPropertyId = new StringValueProperty(); |
| private final BoolValueProperty myAdsEnabled = new BoolValueProperty(); |
| private final ObservableList<String> myAccountNames = new ObservableList<String>(); |
| private final ObservableList<String> myPropertyNames = new ObservableList<String>(); |
| |
| @SuppressWarnings("FieldCanBeLocal") // Declared as field to prevent garbage collection |
| private final BindingsManager myBindings = new BindingsManager(); |
| |
| @SuppressWarnings("FieldCanBeLocal") // Declared as field to prevent weak reference collection |
| private final InvalidationListener myLoginListener = new InvalidationListener() { |
| @Override |
| protected void onInvalidated(@NotNull Observable sender) { |
| if (myLoggedIn.get()) { |
| refreshProjects(); |
| } |
| else { |
| myAccounts.clear(); |
| myProperties.clear(); |
| myAccountIndex.set(-1); |
| myPropertyIndex.set(-1); |
| } |
| } |
| }; |
| |
| public AnalyticsServiceCreator() { |
| myLoggedIn.addWeakListener(myLoginListener); |
| |
| // Map accounts to account names |
| myBindings.bindList(myAccountNames, new AbstractMapExpression<Account, String>(myAccounts) { |
| @NotNull |
| @Override |
| protected String transform(@NotNull Account account) { |
| return account.getName(); |
| } |
| }); |
| |
| // Map properties to property names |
| myBindings.bindList(myPropertyNames, new AbstractMapExpression<Webproperty, String>(myProperties) { |
| @NotNull |
| @Override |
| protected String transform(@NotNull Webproperty property) { |
| return property.getName(); |
| } |
| }); |
| |
| myAccountIndex.addListener(new InvalidationListener() { |
| @Override |
| protected void onInvalidated(@NotNull Observable sender) { |
| if (myAccountIndex.get() >= 0) { |
| refreshProperties(); |
| } |
| } |
| }); |
| |
| myPropertyIndex.addListener(new InvalidationListener() { |
| @Override |
| protected void onInvalidated(@NotNull Observable sender) { |
| if (myPropertyIndex.get() >= 0) { |
| //noinspection ConstantConditions |
| myPropertyId.set(myProperties.get(myPropertyIndex.get()).getId()); |
| } |
| } |
| }); |
| } |
| |
| @NotNull |
| @Override |
| protected String getResourceRoot() { |
| return "/analytics"; |
| } |
| |
| @NotNull |
| @Override |
| protected String[] getResources() { |
| return new String[]{"AnalyticsTrackers.java.ftl", "AndroidManifest.xml", "app_tracker.xml.ftl", "logo_analytics_color_2x_web_32dp.png", |
| "recipe.xml", "service.xml"}; |
| } |
| |
| @Override |
| protected void initializeContext(@NotNull ServiceContext serviceContext) { |
| GoogleServiceCreators.initializeGoogleContext(serviceContext); |
| |
| serviceContext.putValue("google.analytics.accounts", myAccountNames); |
| serviceContext.putValue("google.analytics.accountIndex", myAccountIndex); |
| serviceContext.putValue("google.analytics.properties", myPropertyNames); |
| serviceContext.putValue("google.analytics.propertyIndex", myPropertyIndex); |
| serviceContext.putValue("google.analytics.hasNoAccount", new SizeExpression(myAccounts).isEqualTo(0).and(myLoggedIn)); |
| serviceContext.putValue("google.analytics.hasAccount", new SizeExpression(myAccounts).isGreaterThan(0)); |
| |
| serviceContext.putAction("google.analytics.refreshProjects", new Runnable() { |
| @Override |
| public void run() { |
| refreshProjects(); |
| } |
| }); |
| serviceContext.putAction("google.analytics.createProject", new Runnable() { |
| @Override |
| public void run() { |
| browse("https://support.google.com/analytics/answer/1008015"); |
| } |
| }); |
| |
| serviceContext.putWatchedValue("google.analytics.propertyId", myPropertyId); |
| serviceContext.putWatchedValue("google.analytics.adsEnabled", myAdsEnabled); |
| |
| serviceContext.setBeforeShownCallback(new Runnable() { |
| @Override |
| public void run() { |
| if (myLoggedIn.get()) { |
| refreshProjects(); |
| } |
| } |
| }); |
| |
| serviceContext.setIsValidCallback(new Callable<Boolean>() { |
| @Override |
| public Boolean call() throws Exception { |
| return !myPropertyId.get().isEmpty(); |
| } |
| }); |
| } |
| |
| private void refreshProjects() { |
| final CredentialedUser user = GoogleLogin.getInstance().getActiveUser(); |
| assert user != null; |
| |
| Callable<Accounts> fetchAccounts = new Callable<Accounts>() { |
| @Override |
| public Accounts call() throws Exception { |
| Analytics analytics = |
| new Analytics.Builder(new NetHttpTransport(), new JacksonFactory(), user.getCredential()).setApplicationName("Android Studio") |
| .build(); |
| |
| Accounts accounts = analytics.management().accounts().list().execute(); |
| if (accounts != null && accounts.getItems().size() > 0) { |
| return accounts; |
| } |
| |
| return null; |
| } |
| }; |
| |
| Dispatchable<Accounts> onAccountsFetched = new Dispatchable<Accounts>() { |
| @Override |
| public void dispatch(@NotNull Accounts accounts) { |
| myAccounts.setAll(accounts.getItems()); |
| myAccountIndex.set(0); |
| } |
| }; |
| |
| runInBackground(fetchAccounts, onAccountsFetched); |
| } |
| |
| private void refreshProperties() { |
| final Account account = myAccounts.get(myAccountIndex.get()); |
| assert account != null; |
| |
| final CredentialedUser user = GoogleLogin.getInstance().getActiveUser(); |
| assert user != null; |
| |
| myPropertyIndex.set(-1); |
| |
| Callable<Webproperties> fetchProperties = new Callable<Webproperties>() { |
| @Override |
| public Webproperties call() throws Exception { |
| Analytics analytics = |
| new Analytics.Builder(new NetHttpTransport(), new JacksonFactory(), user.getCredential()).setApplicationName("Android Studio") |
| .build(); |
| |
| String id = account.getId(); |
| Webproperties properties = analytics.management().webproperties().list(id).execute(); |
| if (properties != null && properties.getItems().size() > 0) { |
| return properties; |
| } |
| |
| return null; |
| } |
| }; |
| |
| Dispatchable<Webproperties> onPropertiesFetched = new Dispatchable<Webproperties>() { |
| @Override |
| public void dispatch(@NotNull Webproperties properties) { |
| myProperties.setAll(properties.getItems()); |
| myPropertyIndex.set(0); |
| } |
| }; |
| |
| runInBackground(fetchProperties, onPropertiesFetched); |
| } |
| } |